zoukankan      html  css  js  c++  java
  • 动态SQL番外篇

    动态(dynamic)SQL

    1.区分静态SQL和动态SQL

    1)静态SQL

    静态SQL指直接嵌入在PL/SQL块中的SQL语句,静态SQL用于完成特定或固定的任务。

    select sal from emp where empno=4000;

    2)动态SQL

    动态SQL运行PL/SQL块时动态输入的SQL语句。如果在PL/SQL需要执行DDL语句,DCL语句,或者需要执行更加灵活的SQL语句(select中有不同的where条件),需要用到动态SQL。

    编译动态SQL语句时,需要将SQL语句存放到字符串变量中,而且SQL语句可以包含占位符(以冒号开始)。

    delete from emp where empno=:v_empno;

    注意:能用静态SQL的一般不推荐使用动态SQL,静态SQL的语句性能较优。

    2.用动态SQL处理非查询语句

    3.使用动态SQL处理多行查询语句

    4.用集合处理动态SQL语句

    5.三种不同的动态SQL方法

    1)使用execute immediate语句

    除不能处理多行查询语句,其他的动态SQL包括DDL语句,DCL语句以及单行的SELECT查询都可以。

    2)使用open-for,fetch,close

    能处理动态的多行查询操作,必须使用open-for语句打开游标,使用fetch语句循环提取数据,最终使用close语句关闭游标。

    3)使用批量动态SQL

    通过使用批量动态SQL语句,可以加快SQL语句处理,进而提高PL/SQL的性能。

    6.execute immediate语法

    execute immediate dynamic_string

    [into {define_variable[,define_variable...]}]

    [using [in|out|in out] bind_argument]

    [{return|returning} into bind_argument...]

    {}中内容是必须存在的。

    1)使用execute immediate语句处理DDL操作

    v=drop table ||v_table_name;

    //删除某个表

    create or replace procedure pro_drop_table(v_table_name varchar2)

    is

    v_sql varchar2(100);

    begin

    v_sql :=’drop table ‘||v_table_name; —注意table后面的空格

    execute immediate v_sql;

    end;

    2)处理DCL操作

    //授予某个权限给某个用户

    create or replace procedure pro_grant_priv(v_priv varchar2,

    v_username varchar2)

    is

    v_sql varchar2(100);

    begin

    v_sql := ‘grant ‘||v_priv||’ to ‘||v_username;

    execute immediate v_sql;

    end;

    ##验证

    create user test identified by test;

    exec pro_grant_priv(‘create session’,'test’);

    oracle>conn test/test;

    3)处理DML操作

    如果DML语句中包含占位符,那么execute immediate语句之后必须带有using语句。如果DML语句中带有returning子句,那么在execute immediate语句之后需要带有returning into子句

    //给不同部门加薪

    declare 

    v_sql varchar2(100);

    begin

    v_sql := ‘update emp set sal = sal*(1+:v_percent/100) where deptno=:v_deptno’;

    execute immediate v_sql using &1,&2;

    end;

    7.使用open-for,fetch,close语句

    ##动态处理select语句返回多行数据

    1)定义游标变量

    type cursor_type is ref cursor;

    cursor_variable cursor_type;

    2)打开游标变量

    open cursor_variable for dynamic_string [using bind_argument...];

    3)循环提取数据

    fetch cursor_variable into {var1,var2…|record_var};

    var提取标量变量,record_var提取记录变量。

    4)关闭游标

    close cursor_variable;

    //显示指定部门的所有雇员名和工资

    create or replace procedure pro_info(v_deptno number)

    is

    type emp_cursor_type is ref cursor;

    emp_cursor emp_cursor_type;

    emp_record emp%rowtype;

    v_sql varchar2(100);

    begin

    v_sql :=’select *  from emp where deptno=:v_deptno’;

    open emp_cursor for v_sql using v_deptno;

    loop

    fetch emp_cursor into emp_record;

    exit when emp_cursor%notfound;

    DBMS_OUTPUT.PUT_LINE(‘ename: ‘||emp_record.ename ||’salary: ‘||emp_record.sal);

    end loop;

    close emp_cursor;

    end;

    8.批量动态游标 –bulk

    bulk加快批量数据的处理速度,使用bulk子句时,实际是动态SQL语句将变量绑定为集合元素。

    集合元素必须使用SQL数据类型(char,number,varchar2,date,timestamp),不能使用PL/SQL数据类型(binary_integer,boolean)。

    1)动态BULK子句的语法:

    execute immediate dynamic_string 

    [bulk collect into define_variable]

    [using bind_argument...]

    [{returning | return} bulk collect into return_variable...]

    2)显示特定部门的所有雇员名

    set serveroutput on;

    declare 

    type ename_table_type is table of emp.ename%type index by binary_integer;

    ename_table ename_table_type;

    v_sql  varchar2(100);

    begin 

    v_sql:=’select ename from emp where deptno=:v_deptno’;

    execute immediate v_sql

    bulk collect into ename_table using &v_deptno;

    for i in 1..ename_table.count loop

    dbms_output.put_line(ename_table(i));

    end loop;

    end;


    声明:OSCHINA 博客文章版权属于作者,受法律保护。未经作者同意不得转载。

  • 相关阅读:
    javascript计算两个时间差
    angular 倒计时15 minute的方法封装
    一个页面多个倒计时的封装
    网站倒计时
    angularjs定时任务的设置与清除
    浏览器Event Loop 是个什么鬼
    一个图片测试的小网站:dummyimage.com
    在vscode 一行的末尾按下tab键 快速生成代码 很爽
    VSCODE 快捷键
    weex 在iOS 平台上的整合
  • 原文地址:https://www.cnblogs.com/JSD1207ZX/p/9386335.html
Copyright © 2011-2022 走看看