您的位置:首页 > 其它

存储过程实例(统计某用户下所有的表的记录数)

2011-08-26 17:46 281 查看
写一个存储过程,统计某用户下所有表的记录数,并将其一一对应的插入表hr.count_all中(hr是Oracle默认存在的账户)

创建count_all的sql语句:

create table hr.count_all(tablename varchar2(50),

count number);

以下PL/SQL块(1)是错误的,在插入一条记录后,循环到第二条记录时会报错

因为if块里面那个字符串v_select_sql一直在增长而没有清空,很显然构造的是

非法的查询串;

(1):

declare

cursor c_tab_name is select table_name from user_tables;

tem_tab_name varchar2(20);

v_count number(8);

v_select_sql varchar(200) default 'select count(*) from emcd.';

v_insert_sql varchar2(200) default 'insert into hr.count_all values(';

begin

open c_tab_name;

loop

fetch c_tab_name into tem_tab_name;

exit when c_tab_name%notfound;

if tem_tab_name is not null then

dbms_output.put_line('table_name ==> '||tem_tab_name);

v_select_sql := v_select_sql||tem_tab_name;

dbms_output.put_line('v_select_sql ==> '||v_select_sql);

execute immediate v_select_sql into v_count;

v_insert_sql := v_insert_sql||''''||tem_tab_name||''','||v_count||')';

dbms_output.put_line('v_insert_sql ==> '||v_insert_sql);

execute immediate v_insert_sql;

commit;

end if;

end loop;

close c_tab_name;

end;

/

(2):

declare

cursor c_tab is select table_name from user_tables; --声明游标

tem_name varchar2(30);

v_count number(8);

--v_select_sql varchar2(200) default 'select count(*)from emcd.';

--v_insert_sql varchar2(200) default 'insert into hr.count_all values(';

v_select_sql varchar2(200);

v_insert_sql varchar2(200);

begin

--注意这里的时间格式mi表示分钟,mm表示月份,若果将hh24:mi:ss写成hh24:mm:ss

--则显示的分钟部分将表示的是月份的值,显然这是错误的,要格外小心.

dbms_output.put_line(to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));

open c_tab; --打开游标

loop

fetch c_tab into tem_name; --取数据

exit when c_tab%notfound;

if tem_name is not null then

--动态sql串.

v_select_sql := 'select count(*)from emcd.';

v_select_sql := v_select_sql ||tem_name;

dbms_output.put_line('v_select_sql ==> '||v_select_sql);

execute immediate v_select_sql into v_count;

v_insert_sql := 'insert into hr.count_all values(';

v_insert_sql := v_insert_sql || ''''||tem_name||''','||v_count||')';

dbms_output.put_line('v_insert_sql ==> '||v_insert_sql);

execute immediate v_insert_sql;

commit;

end if;

end loop;

close c_tab; --循环结束后关闭游标

dbms_output.put_line(to_char(sysdate,'yyyy-mm-dd hh24:mi:ss'));

end;

===========================================================================

--根据输入的用户名,统计该用户下所有表的记录数到用户HR下的表count_all里面

--count_all的表只有两个字段:tablename varchar(30),count number

--以emcd登录SQLplus编译执行该存储过程时,要保证不出错则必须emcd用户对视图dba_objects

--有select权限,对HR用户的表count_all有insert权限,对任何表有select权限。

--相关的授权语句如下:

-- grant select any table to emcd;

-- grant select on dba_objects to emcd;

-- grant insert,update on hr.count_all to emcd;

--以相应的用户登录执行授权语句后就可保证emcd用户成功地编译执行该存储过程

CREATE OR REPLACE PROCEDURE EMCD.count_all(var_user in varchar2)

AS

CURSOR c_tab

IS

SELECT object_name

FROM dba_objects

WHERE object_type = 'TABLE' AND owner = upper(var_user)

ORDER BY 1;

v_count NUMBER;

v_insert_sql VARCHAR2 (200);

v_select_sql VARCHAR2 (200);

tem_tab VARCHAR2 (50);

--counters number := 0;

BEGIN

DBMS_OUTPUT.put_line ('====Begin here!====');

OPEN c_tab;

DBMS_OUTPUT.put_line ( 'Begin ==> ' || TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));

LOOP

FETCH c_tab

INTO tem_tab;

IF c_tab%NOTFOUND

THEN

EXIT;

END IF;

IF tem_tab IS NOT NULL

THEN

--counters := counters + 1;

v_select_sql := 'select count(*)from '||var_user||'.';

v_select_sql := v_select_sql || tem_tab;

EXECUTE IMMEDIATE v_select_sql INTO v_count;

v_insert_sql := 'insert into hr.count_all values(';

v_insert_sql := v_insert_sql || '''' || tem_tab || ''',' || v_count || ')';

EXECUTE IMMEDIATE v_insert_sql;

END IF;

END LOOP;

select count(*) into v_count from HR.COUNT_ALL;

update HR.COUNT_ALL set count=v_count where tablename='COUNT_ALL';

CLOSE c_tab;

COMMIT;

DBMS_OUTPUT.put_line (TO_CHAR (SYSDATE, 'yyyy-mm-dd hh24:mi:ss'));

END;

注意:

在sqlplus里编译的时候如果当前用户emcd对dba_objects没有select权限,则编译错误;

输入:show error 回车会显示错误 :PL/SQL: ORA-00942: 表或视图不存在。以sys作为dba登录

授予权限:grant select on dba_objects to emcd; grant select any table to emcd; 之后编译通过。

但是还要注意一点就是emcd用户对用户hr的表count_all必须update 和insert的权限,否则在执行

命令:exec emcd.count_all 调用该存储过程时会报错。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: