使用 DB Link 从远程表获取数据的 PL/SQL 过程

问题描述 投票:0回答:1

我对 PL/SQL 编程完全陌生..

我的要求是收集特定模式下的表列表、其计数(*)和行数以及 n 个数据库的最后分析日期,并将其填充到单个表中。我正在尝试通过数据库链接访问远程数据库。在互联网资源的帮助下设法编写了以下代码。但无法获得输出。请帮忙解决这个问题..

CREATE OR REPLACE PROCEDURE fetch_tables_stats
AS
BEGIN
  FOR src_link IN (SELECT db_link FROM dba_db_links WHERE USERNAME = '<user>') 
  LOOP
    FOR tbl IN (SELECT table_name FROM dba_tables@src_link.db_link WHERE owner = '<owner>')
    LOOP
      DECLARE
      v_row_count NUMBER;
      v_num_rows NUMBER;
      sql_stmt1 VARCHAR2(1000);
      sql_stmt2 VARCHAR2(1000);
      BEGIN
        sql_stmt1 := 'SELECT COUNT(*) FROM ' || tbl || '.' || table_name || '@' ||src_link || '.' || db_link;
        EXECUTE IMMEDIATE sql_stmt1 INTO v_row_count;
        sql_stmt2 := 'SELECT num_rows FROM dba_tab_statistics@' || src_link || '.' || db_link || ' WHERE table_name = ' || tbl ||'.' || table_name || ' AND owner = ' || q'['<owner>']';  
        EXECUTE IMMEDIATE sql_stmt2 INTO v_num_rows;
        INSERT INTO SWMS_TAB_COUNT_STATS_RDS (OPCO_NAME,TABLE_NAME,ACTUAL_ROWCOUNT,STATS_NUM_ROWS,STATS_DATE)
        VALUES (src_link.db_link,tbl.table_name, v_row_count, v_num_rows,sysdate);
        COMMIT;
      END;
    END LOOP;
  END LOOP; 
END fetch_tables_stats;
/ 

输出:

LINE/COL ERROR
-------- -----------------------------------------------------------------
6/17     PL/SQL: ORA-00942: table or view does not exist
6/17     PL/SQL: SQL Statement ignored
14/6     PL/SQL: Statement ignored
14/46    PLS-00364: loop index variable 'TBL' use is invalid
16/3     PL/SQL: Statement ignored
16/16    PLS-00306: wrong number or types of arguments in call to '||'
18/6     PL/SQL: SQL Statement ignored
19/34    PLS-00364: loop index variable 'TBL' use is invalid
19/38    PL/SQL: ORA-00984: column not allowed here
SQL>
oracle loops plsql nested dblink
1个回答
0
投票

由于您必须在查询中包含表名称和数据库链接名称,因此您需要动态 SQL

这是一个例子;我正在使用

user_...
表,因为我无法访问
dba_...
的表,所以 - 你必须解决这个问题。另外,我只是将输出显示到屏幕上 - 您将其插入到表中(也修复它)。

SQL> set serveroutput on
SQL> declare
  2    rc           sys_refcursor;
  3    l_table_name user_tables.table_name%type;
  4    l_cnt        number;
  5  begin
  6    for src_link in (select db_link from user_db_links) loop
  7
  8      open rc for 'select table_name from user_tables@' || src_link.db_link;
  9
 10      loop
 11        fetch rc into l_table_name;
 12        exit when rc%notfound;
 13
 14        execute immediate 'select count(*) from ' || l_table_name ||'@'|| src_link.db_link
 15          into l_cnt;
 16
 17        dbms_output.put_line(l_table_name||'@'|| src_link.db_link ||' -> ' || l_cnt || ' row(s)');
 18      end loop;
 19
 20      close rc;
 21    end loop;
 22  end;
 23  /
BONUS@DBL_MIKE -> 0 row(s)
DUMMY@DBL_MIKE -> 1 row(s)
SALGRADE@DBL_MIKE -> 5 row(s)
DEMO_TAGS@DBL_MIKE -> 6 row(s)
<snip>

PL/SQL procedure successfully completed.

SQL>
© www.soinside.com 2019 - 2024. All rights reserved.