我对 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>
由于您必须在查询中包含表名称和数据库链接名称,因此您需要动态 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>