ORACLE动态SQL笔记

下面的验证是在PL/SQL developer8 上面编写和验证。窗口为SQL WINDOWS;

1,使用execute immediate处理DDL操作
在PL/SQL处理DDL语句时,execute immediate后面只需要带有ddl语句文本即可,而不需要into和using子句:
example1:
create or replace procedure pro_drop_table(p_table_name varchar2) is
  sql_statement varchar2(100);
begin
  sql_statement := 'drop table ' || p_table_name;
  execute immediate sql_statement;
end;

表test2已经存在数据库中,验证如下:
begin
  pro_drop_table('test2');
  end;

2,使用execute immediate处理DCL操作

 在PL/SQL处理DDL语句时,execute immediate后面只需要带有dcl语句文本即可,而不需要into和using子句:
example2:

create or replace procedure pro_grant_sys_priv(p_priv     varchar2,
                                               p_username varchar2) is
  sql_statement varchar2(100);
begin
  sql_statement := 'grant ' || p_priv || ' to ' || p_username;
  execute immediate sql_statement;
end;

验证如下:
begin
  pro_grant_sys_priv('create session', 'scott');
end;

3,使用execute immediate处理DML操作
当使用execute immediate 处理dml语句时,如果dml语句没有占位符,也没有returning子句,那么在execute immediate
语句之后不需要带有using和returning into子句。
(1)处理无占位符和returning子句的DML语句

declare
  sql_statement varchar2(100);
begin
  sql_statement := 'update emp set sal = sal* 1.1 where deptno=30';
  execute immediate sql_statement;
end;

(2)处理包含占位符的DML语句
declare
  sql_statement varchar2(100);
begin
  sql_statement := 'update emp set sal = sal* (1+:percent/100) ' || ' where deptno=:dno'';
  execute immediate sql_statement using &1,&2;
  end;

 (3)处理包含RETURNING子句的DML语句
declare
  salary        number(6, 2);
  sql_statement varchar2(100);
begin
  sql_statement := 'update emp set sal = sal *(1+:percent/100)' ||  ' where empno = :eno  returning sal into :salary ';
  execute immediate sql_statement
    using &1, &2
    returning into salary;
  dbms_output.put_line('新工资:' || salary);
end;

4,使用execute immediate 处理单行查询
declare
  sql_statement varchar2(100);
  emp_record    emp%rowtype;
begin
  sql_statement := 'select * from emp where empno = :eno';
  execute immediate sql_statement
    into emp_record
    using &1;
  dbms_output.put_line('雇员 ' || emp_record.ename || '的工资为' ||
                       emp_record.sal);
end;

5,动态SQL处理多行查询语句,需要使用OPEN-FOR,FETCH和CLOSE 语句。
---定义游标变量---打开游标变量---循环游标变量---关闭游标变量
(1),定义游标变量语法
declare type cursor_name is ref cursor;
cursor_variable cursor_name;
(2),打开游标变量语法
OPEN cursor_variable for dynamic_string [USING bind_argument[,bin_argument]...];
--dynamic_string是动态的select语句,bind_argument用于指定存放传递给动态select语句值的变量。
(3),循环提取数据语法
FETCH cursor_variable INTO {var1[,var2]..|  record_var};
--var是用于接收提取结果的变量;record_var是用于接收提取结果的记录变量。
(4),关闭游标
CLOSE cursor_variable;
(5),查询示例:

  declare
    type emp_cur_type is ref cursor;
    emp_cur       emp_cur_type;
    emp_record    emp%rowtype;
    sql_statement varchar2(200);
  begin
    sql_statement := 'select * from emp where deptno = :dno';
    open emp_cur for sql_statement
      using &dno;
    loop
      fetch emp_cur
        into emp_record;
      exit when emp_cur%notfound;
      dbms_output.put_line('雇员名:' || emp_record.ename || ',工资' ||
                           emp_record.sal);
    end loop;
  end; 

6,在动态SQL语句中使用BULK子句,实际是动态SQL语句将变量绑定为集合元素。
集合类型可以是PL/SQL所支持的索引表,嵌套表和VARRY;当集合元素必须使用SQL数据类型(number,char等),
而不能使用PL/SQL数据类型(如binary_integer,boolean等);有三种支持BULK子句:EXECUTE IMMEDIATE,FETCH,
FORALL,下面分别介绍在这三种语句中使用BULK子句的方法。

(1)使用bulk子句处理DML语句返回子句

 declare
    type ename_table_type is table of emp.ename%type index by binary_integer;
    type sal_table_type is table of emp.sal%type index by binary_integer;
    ename_table   ename_table_type;
    sal_table     sal_table_type;
    sql_statement varchar2(200);
  begin
    sql_statement := 'update emp set sal = sal*(1+percent/100)' ||
                     ' where deptno=:dno' ||
                     ' returing ename,sal into :name,:salary';
    execute immediate sql_statement
      using &percent,&dno
      returning bulk collect
      into ename_table, sal_table;
    for i in 1..ename_table.count loop
      dbms_output.put_line('雇员' || ename_table(i) || '的新工资为' ||
                           sal_table(i));
    end loop;
  end;

posted @ 2011-08-12 10:30  痞子过  阅读(265)  评论(0编辑  收藏  举报