Chinaunix首页 | 论坛 | 博客
  • 博客访问: 380583
  • 博文数量: 113
  • 博客积分: 3035
  • 博客等级: 中校
  • 技术积分: 1430
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-01 16:32
文章分类
文章存档

2011年(42)

2010年(70)

2009年(1)

我的朋友

分类: 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




 

阅读(3723) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~