存储过程实例(统计某用户下所有的表的记录数)
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 调用该存储过程时会报错。
创建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 调用该存储过程时会报错。
相关文章推荐
- 统计Oracle当前用户下所有表中的记录数
- 使用mysql存储过程-统计某个数据库下的所有表的记录数
- Oracle统计某用户下所有的表的记录数
- SQL--统计出所有数据库内用户表的记录总数
- 统计ORACLE当前用户下所有表中的记录数
- Oracle存储过程,统计Oracle当前用户下所有表中的记录数
- 简单统计SQLSERVER用户数据表大小(包括记录总数和空间占用情况)
- SQLSERVER中统计所有表的记录数
- 查询Oracle所有用户下各表里面的记录数
- 一条SQL删除所有用户自定义数据表,存储过程
- Oracle 10g Audit(审计) --- 记录登录用户在Oracle中的所有操作(转)
- 统计当前数据库所有表的记录数
- 通过登入IP记录Linux所有用户登录所操作的日志
- SQL:统计一个数据库中所有表记录的数量
- 通过SpringAOP获取request中所有参数,记录用户操作日志
- linux开启user_cmd功能记录用户所有操作指令到log message
- SQLSERVER中统计所有表的记录数
- Linux下记录所有用户操作的脚本
- scala实战之spark用户在线时长和登录次数统计实例