美文网首页
Oracle PL/SQL (12) - 动态SQL语句

Oracle PL/SQL (12) - 动态SQL语句

作者: 乘风破浪的姐姐 | 来源:发表于2020-05-07 17:15 被阅读0次

    1.静态SQL与动态SQL
    Oracle编译PL/SQL程序块分为两个种:一种是,SQL语句在程序编译期间就已经确定,大多数的编译情况属于这种类型,如:静态SQL;另外一种是SQL语句只有在运行阶段才能建立,例如当查询条件为用户输入时,那么Oracle的SQL引擎就无法在编译期对该程序语句进行确定,只能在用户输入一定的查询条件后才能提交给SQL引擎进行处理。如:动态SQL。
    本文主要就动态SQL的基础做总结。

    2.使用EXECUTE IMMEDIATE语句处理相关语句:
    动态SQL是一种”不确定”的SQL,那其执行就有其相应的特点。Oracle中提供了Execute immediate语句来执行动态SQL,语法如下:

    Excute immediate 动态SQL语句 using 绑定参数列表 returning into 输出参数列表;
    
    1. USING 子句给动态语句传值
      例如:
    declare 
      l_str1 varchar2(20) := 'hello'; 
      l_str2    varchar2(10) := 'world'; 
      begin 
      execute immediate 'insert into t_str values   (:1, :2, :3)' 
       using 50, l_str1 , l_str2 ; 
     commit;   -----一定要显示提交
    end; 
    

    4.INTO子句从动态语句检索值
    例如:

    declare 
     v_cnt    varchar2(20); 
    begin 
      execute immediate 'select count(1) from emp'  into v_cnt    ; 
     dbms_output.put_line(v_cnt ); 
    end; 
    

    5.传递并检索值.INTO子句用在USING子句前
    例如:

    declare 
     v_empno    pls_integer := 20; 
     v_ename     varchar2(20); 
     v_esex     varchar2(20); 
    begin 
      execute immediate 'select ename, esex from emp where empno = :1' 
       into v_ename,v_esex 
       using v_empno   ; 
    end; 
    

    6.输出参数returning into 子句用在USING子句后
    例如:

    create or replace procedure update_data(stuid varchar2, age number)
    as
       strSQL varchar2(1000);
       strID varchar2(50);
       strName varchar2(50);
       strSex varchar2(50);
    begin
       strSQL := 'update tb_student set age=:a where id=:b returning id, name, sex into :c, :d, :e';
       execute immediate strSQL using age, stuid returning into strID, strName, strSex;
       execute immediate 'commit'; -- 这样也是可以的
       dbms_output.put_line('ID:' || strID || ' ;Name:' || strName || ' ;Sex:' || strSex);
    end;
    

    在上面的代码中,:a、:b、:c、:d和:e都是占位符,占位符必须以冒号开始,名字无所谓。使用了占位符以后,就需要在execute immediate语句后面使用using将参数传递进去,参数将与占位符一一对应。但是有一点需要谨记,绑定参数不能是表名、列名、数据类型等,绑定参数只能是值、变量或者表达式。用DDL语句动态创建对象时,应该使用连接运算符||,最好不要使用绑定参数。
    另外上述代码中还使用了一个returning into的关键语句,returning into语句的主要作用是:
    delete操作:returning返回的是delete之前的结果
    insert操作:returning返回的是insert之后的结果
    update操作:returning语句是返回update之后的结果

    7.通过游标实现多行查询的SELECT语句
    例如:

    declare
      type ref_cur is ref cursor;
      rc ref_cur;
      seriesrow t_Md_Vehicle_Series%rowtype;
      v_sql varchar2(500):='select * from t_Md_Vehicle_Series m where m.vehicle_make_id=:makeid';
      v_sql2 varchar2(500);
      type tb_model_type is table of t_md_vehicle_model%rowtype;
       model_array tb_model_type;
    begin
     DBMS_OUTPUT.ENABLE(100000);
    
      open rc for v_sql using 'CN001';
      loop
         FETCH rc INTO seriesrow;
           EXIT WHEN rc%NOTFOUND;
           dbms_output.put_line('name:'||seriesrow.vehicle_series_name||'-------------->  id:'||seriesrow.vehicle_series_id);
           v_sql2:='select * from t_md_vehicle_model m where m.vehicle_series_id=:seriesid and m.valid_flag=1'; 
           execute immediate v_sql2 bulk collect into model_array using seriesrow.vehicle_series_id;
           for i in model_array.first .. model_array.last loop
           dbms_output.put_line('ID:' || model_array(i).vehicle_sub_model_id 
                               || '-------------->  Name:' || model_array(i).vehicle_sub_model_name  );
       end loop;
      end loop;
      CLOSE rc;
    end;
    

    输出结果:


    image.png

    上述语句中,用带有子句bulk collect into的execute immediate语句。采用bulk collect into可以将查询结果一次性地加载到集合中,可以在select into、fetch into、returning into语句中使用bulk collect into;但是需要特别注意的是,在使用bulk collect into时,所有的into变量都必须是集合类型。

    相关文章

      网友评论

          本文标题:Oracle PL/SQL (12) - 动态SQL语句

          本文链接:https://www.haomeiwen.com/subject/enrrihtx.html