zoukankan      html  css  js  c++  java
  • 动态游标(例如表名作为参数)以及动态SQL分析

    表名作为参数的动态游标

    DECLARE
       v_table_name VARCHAR2(30) := 'CUX_MES_WIP_BARCODE_MAP';
       --l_rec        SYS_REFCURSOR;
       TYPE t_data IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
       TYPE t_cur IS REF CURSOR;
       l_data       t_data;
       l_rec        t_cur;
       l_cur        VARCHAR2(4000);
       v_fm_barcode VARCHAR2(30) := 'cxy-p-001';
       v_to_barcode VARCHAR2(30) := 'cxy-p-002';
       v_barcode    VARCHAR2(30);
    BEGIN
    
       l_cur := 'select barcode from ' || v_table_name || ' where barcode >= ' ||
                ''''||v_fm_barcode||'''' || ' and barcode <= ' ||
                ''''||v_to_barcode || '''';
       dbms_output.put_line(l_cur);
       OPEN l_rec FOR l_cur;
       LOOP
          EXIT WHEN l_rec%NOTFOUND;
          FETCH l_rec BULK COLLECT
             INTO l_data;
          FOR i IN 1 .. l_data.count LOOP
          
             dbms_output.put_line(l_data(i));
          END LOOP;
       
       END LOOP;
    END;
    

    动态SQL

    /*
     1.什么是动态SQL?
     动态SQL是指在运行PL/SQL块时动态输入SQL语句。在PL/SQL块中只能执行DDL(create、alter、drop)、DCL
     (grant、revoke)或比较灵活的SQL语句(如select子句不带where条件);
     动态SQL的性能不如静态SQL,但是比较灵活;
     在PL/SQL块中编写动态SQL语句时需要将SQL语句存放到字符串变量中而且SQL语句可以包含占位符(以冒号开始);
     
    
    2.动态SQL的语法
     2.1 使用execute immediate语句
     可以处理多数动态SQL操作如:DDL语句(create、alter、drop)、DML语句(insert、update、delete)、DCL(grant、revoke)
     以及单行的select子句;但是不能处理多行查询语句。
     
    
    2.2 使用open...for,fetch和close语句
     
    在游标中使用。
     
    
    2.3 使用批量动态SQL语句
     
    */
     
    ---------------------------------------------------------------
     ***************************************************************
     1. 使用execute immediate
     
    ---------------------------------------------------------------
     1.1 使用execute immediate处理DDL语句
     ---------------------------------------------------------------
     
    
    --案例01:使用execute immediate处理DDL语句--create
     
    declare
     create_table  varchar2(200);
     begin
     create_table:='create table ' ||'&table_name' ||'(sid int, sno int)';
     execute  immediate create_table  ;
     end;
     
     
     
    
    --案例02:使用execute immediate处理DDL语句---alter
     
    declare
     alter_table  varchar2(200);
     begin
     alter_table:='alter table &target_table_name modify &column_name varchar2(10)';
     execute  immediate alter_table  ;
     end;
     
     
     
     
     
    --案例03:使用execute immediate处理DDL语句---drop
     
    
    declare
     drop_table  varchar2(200);
     begin
     drop_table:='drop table ' ||'&target_table_name';
     execute  immediate drop_table  ;
     end;
     
     
     
    --案例04:使用execute immediate处理DDL语句--drop table
     
    create or replace procedure drop_table (table_name varchar2)
     is 
    sql_sta varchar2(200);
     begin
     sql_sta:='drop table ' ||table_name;
     execute immediate sql_sta;
     end;
     
    
    --调用方法:
     exec drop_table('accp');
     
     
     
    --案例05:使用execute immediate处理DDL语句--create+select
     declare
     select_sta varchar2(200);
     emp_rec emp%rowtype;
     begin
     execute immediate
     'create table sodi(sid int, sno int)';
     select_sta:='select * from emp where empno=:id';
     execute  immediate select_sta  into emp_rec using &1;   /*使用占位符时,这个占位符是在引号内使用的*/
     end;
     
     
     
    
    ---------------------------------------------------------
     1.2 使用execute immediate处理DCL语句
     ----------------------------------------------------------
     
     
     
    --案例01:使用execute immediate处理DCL语句--grant
     
    create or replace procedure grant_priv(priv varchar2, username varchar2)
     is
     priv_stat varchar2(200);
     begin
     priv_stat:=' grant '|| priv || ' to ' || username; --注意字符串和连接符之间的空格
     execute immediate priv_stat;
     end;
     
    --调用方法
      exec grant_priv('create session', 'scott');
     
     
     
    --案例02:使用execute immediate处理DCL语句--revoke
     
    create or replace procedure revoke_priv(priv varchar2, username varchar2)
     is
     priv_stat varchar2(200);
     begin
     priv_stat:=' revoke '|| priv || ' from ' || username; --注意字符串和连接符之间的空格
     execute immediate priv_stat;
     end;
     
    --调用方法
      exec revoke_priv('create session', 'scott');
     
     
     
    
    ----------------------------------------------------------------
     1.3.使用execute immediate处理DML语句
     ----------------------------------------------------------------
     
    1.处理无占位符和return子句的DML语句
     
    --案例01:查询子句:select
     
    declare
     sql_stat varchar2(100);
     begin
     sql_stat:='select * from emp';
     execute immediate sql_stat;
     end;
     
    
    --案例02:处理无占位符和return子句的DML语句--insert
     declare
     insert_table varchar2(200);
     begin
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     end;
     
    
    --案例03:处理无占位符和return子句的DML语句--update
     declare
     update_table varchar2(200);
     begin
     update_table:='update &table_name set &column_name=&new_value ';
     execute immediate update_table;
     end;
     
     
     
    --案例06:处理无占位符和return子句的DML语句--delete
     declare
     delete_table varchar2(200);
     begin
     delete_table:='delete from  &table_name  ';
     execute immediate delete_table;
     end;
     
     
     
     
     
     
     
    
    --案例05:新建一个表然后插入数据--create+insert
     
    declare
     create_table  varchar2(200);
     begin
     create_table:='create table &table_name(sid int, sno int)';
     execute  immediate create_table  ;
     end;
     
    
    declare
     insert_table varchar2(200);
     begin
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     end;
     
    
    --案例06:同时实现新建一个表并插入数据--create+insert
     
    declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     end;
     
     
     
    
    --案例07:同时实现新建一个表并插入数据--create+insert+update
     /*
     这里也可以分开写
     
    */
     
    
    declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     update_table:='update &table_name set &column_name=&new_value where sid=&old_value';
     execute immediate update_table;
     end;
     
     
     
    
    --案例08:同时实现新建一个表并插入数据--create+insert+update+delete
     declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     delete_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     update_table:='update &table_name set &column_name=&new_value where sid=&old_value';
     execute immediate update_table;
     delete_table:='delete from &delete_tablename';
     execute immediate delete_table;
     end;
     
     
     
    
    --案例08:同时实现新建一个表并插入数据--create+insert+update+delete+insert
     declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     delete_table varchar2(200);
     re_insert_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &table_name values (&sid, &sno)';
     execute immediate insert_table;
     update_table:='update &table_name set &column_name=&new_value where sid=&old_value';
     execute immediate update_table;
     delete_table:='delete from &delete_tablename';
     execute immediate delete_table;
     re_insert_table:='insert into &re_table_name values (&new_sid, &new_sno)';
     execute immediate re_insert_table;
     end;
     
     
     
     
     
     
     
    
    2.处理占位符的DML语句
     
    
    --案例01:处理占位符的DML语句:create+insert
     declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &target_table_name values (:sid, :sno)';
     execute immediate insert_table using  &2,&3;
     end;
     
    
    --案例02:处理占位符的DML语句:create+insert_update
     declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &target_table_name values (:sid, :sno)';
     execute immediate insert_table using  &1,&2;
     update_table:='update &update_tablename set &update_column_name=:new_value where &condition_column=:old_value ';
     execute immediate update_table using &3 ,&4;
     end;
     
    
    ---or
     declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     begin
     create_table:='create table &新建的表名 (sid int, sno int)';
     execute  immediate create_table  ;
     insert_table:='insert into &插入数据的表名 values (:sid, :sno)';
     execute immediate insert_table using  &sid的值 ,&sno的值;
     update_table:='update &被更新的表名 set &更新的列名=:new_value where &条件列=:old_value ';
     execute immediate update_table using &新值 ,&条件列的值;
     end;
     
     
     
    
    --案例03:处理占位符的DML语句:create+update+insert+delete
     
    declare
     create_table  varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     delete_table varchar2(200);
     begin
     create_table:='create table &table_name (sid int, sno int)';
     execute  immediate create_table  ;
     
    insert_table:='insert into &target_table_name values (:sid, :sno)';
     execute immediate insert_table using  &1,&2;
     
    update_table:='update &update_tablename set &update_column_name=:new_value where &update_condition_column=:delete_condition_column_value ';
     execute immediate update_table using &3 ,&4;
     
    delete_table:='delete from &dele_table_name where &delete_condition_column=:delete_condition_column_value';
     execute immediate delete_table using &5;
     end;
     
     
     
    ---执行过程:
     SQL> declare
       2  create_table  varchar2(200);
       3  insert_table varchar2(200);
       4  update_table varchar2(200);
       5  delete_table varchar2(200);
       6  begin
       7  create_table:='create table &table_name (sid int, sno int)';
       8  execute  immediate create_table  ;
       9
      10  insert_table:='insert into &target_table_name values (:sid, :sno)';
      11  execute immediate insert_table using  &1,&2;
      12
      13  update_table:='update &update_tablename set &update_column_name=:new_value
     where &update_condition_column=:delete_condition_column_value ';
      14  execute immediate update_table using &3 ,&4;
      15
      16  delete_table:='delete from &dele_table_name where &delete_condition_column=
     :delete_condition_column_value';
      17  execute immediate delete_table using &5;
      18  end;
      19  /
     输入 table_name 的值:  sz
     原值    7: create_table:='create table &table_name (sid int, sno int)';
     新值    7: create_table:='create table sz (sid int, sno int)';
     输入 target_table_name 的值:  sz
     原值   10: insert_table:='insert into &target_table_name values (:sid, :sno)';
     新值   10: insert_table:='insert into sz values (:sid, :sno)';
     输入 1 的值:  101
     输入 2 的值:  201
     原值   11: execute immediate insert_table using  &1,&2;
     新值   11: execute immediate insert_table using  101,201;
     输入 update_tablename 的值:  sz
     输入 update_column_name 的值:  sid
     输入 update_condition_column 的值:  sno
     原值   13: update_table:='update &update_tablename set &update_column_name=:new_
     value where &update_condition_column=:delete_condition_column_value ';
     新值   13: update_table:='update sz set sid=:new_value where sno=:delete_conditi
     on_column_value ';
     输入 3 的值:  1001
     输入 4 的值:  201
     原值   14: execute immediate update_table using &3 ,&4;
     新值   14: execute immediate update_table using 1001 ,201;
     输入 dele_table_name 的值:  sz
     输入 delete_condition_column 的值:  sno
     原值   16: delete_table:='delete from &dele_table_name where &delete_condition_c
     olumn=:delete_condition_column_value';
     新值   16: delete_table:='delete from sz where sno=:delete_condition_column_valu
     e';
     输入 5 的值:  201
     原值   17: execute immediate delete_table using &5;
     新值   17: execute immediate delete_table using 201;
     
    PL/SQL 过程已成功完成。
     
    SQL> select * from sz;
     
    未选定行
     
     
     
    
    3.处理包含returning子句的DML语句
     
    --案例01:处理包含returning子句的DML语句--create+insert+update
     declare
     create_table varchar2(200);
     insert_table varchar2(200);
     update_table varchar2(200);
     res varchar2(100);
     begin
     create_table:='create table &new_table_name (sid int, sno int)';
     execute immediate create_table;
     insert_table:='insert into &insert_target_table_name values (:sid, :sno)';
     execute immediate insert_table using &1,&2 ;
     update_table:='update &update_target_table_name set &udpate_column_name=:new_value where &condition_column_name=:old_value  returning &returning_name into :res';
     execute immediate update_table using &3,&4
     returning into res;
     dbms_output.put_line('the result is : ' ||res);
     end;





  • 相关阅读:
    谷歌浏览器插件开发Tutorial: Getting Started (Hello, World!) 教程:准备开始(你好,世界!)
    Android ViewPager多页面滑动切换以及动画效果
    4.4 我同意条款—CheckBox的isCheck属性
    4.2设计具有背景图的按钮—ImageButton的焦点及事件处理
    【文件打开】浏览打开窗口
    【原创】PE检测工具
    emu8086注册算法分析及KeyGen实现
    学破解 <一> PE格式之MSDOS MZ header
    学破解 <二> PE格式之IMAGE_NT_HEADERS
    反虚拟机程序测试
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299279.html
Copyright © 2011-2022 走看看