分类: Oracle
2010-07-28 14:43:39
写法一:用变量
sessionA>create or replace procedure t_p is
2 x varchar(20) :='abb';
3 begin
4 dbms_output.put_line(x);
5 execute immediate ('insert into big_table_1 values ('''||x||''');
6 end;
7 /
Procedure created.
写法二: 直接用值
create or replace procedure t_p is
begin
dbms_output.put_line('insert into big_table_1 values (''abb'')');
end;
注意在匿名块中执行sql语句要用execute immediate
写法三:在create table时如果没有权限加 Authid Current_User
create or replace procedure create_big_table Authid Current_User is
begin
execute immediate 'create table big_table_1 (name char(2000))';
for x in 1..200 loop
execute immediate 'insert into big_table_1 values (''abb'')';
end loop;
commit;
end;
增补:获取当前用户的所有表以及每张表的行数,汇总到统计表中。
写法1:隐式游标
drop table xyrows
create table XYROWS
(
table_name VARCHAR2(1000),
table_rows number(9)
)
declare
cnt number;
v_str varchar2(100);
BEGIN
for x in (select table_name from user_tables) loop
v_str:= 'select count(*) from '||x.table_name;
execute immediate v_str into cnt;
IF cnt>500000 THEN
insert into xyrows values(x.table_name,cnt);
END IF;
end loop;
commit;
END;
/
写法2:显示游标
declare
cursor c4 is
select table_name from user_tables;
x c4%rowtype;
cnt number;
str varchar2(2000);
BEGIN
if c4%isopen = false then
open c4;
end if;
loop
fetch c4 into x;
str:= 'SELECT COUNT(*) FROM '|| x.table_name;
execute immediate str into cnt;
IF cnt>&rowcount THEN
dbms_output.put_line(x.table_name);
insert into xyrows values (x.table_name,cnt);
END IF;
exit when c4%notfound;
end loop;
commit;
close c4;
END;
/
写法3:定义游标,隐式使用
declare
cursor c4 is
select table_name from user_tables;
x c4%rowtype;
cnt number;
str varchar2(2000);
BEGIN
for x in c4 loop
--str := 'SELECT COUNT(*) into cnt FROM '|| x.table_name;
--execute immediate str;
str:= 'SELECT COUNT(*) FROM '|| x.table_name;
execute immediate str into cnt;
IF cnt>&1 THEN
insert into xyrows values(x.table_name,cnt);
END IF;
end loop;
commit;
END;
/
小结:
1.from后面使用变量,则必须使用动态sql,即execute immediate的写法,推测是和执行计划有关
2.select的值要用execute immediate str into cnt;输出到变量
3.显示游标要有四步:声明,打开,fetch,关闭,并且要声明游标变量,比如这里的x
使用for x in cursor的写法则会隐式的打开和关闭游标
4.要在非sys用户下执行
5.不能直接使用游标变量,要用x.table_name类似这样的写法
6.DBMS_OUTPUT.PUT_LINE();输出的字符长度单行不能超过255,否则会报错
ORA-06502: PL/SQL: numeric or value error: host bind array too small
ORA-06512: at line 1
需要在代码前加上dbms_output.enable(10000);增大显示的缓冲字节
总输出也不能超过1000000