<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Dict.CN 在線詞典, 英語學習, 在線翻譯

    都市淘沙者

    荔枝FM Everyone can be host

    統計

    留言簿(23)

    積分與排名

    優秀學習網站

    友情連接

    閱讀排行榜

    評論排行榜

    PL/SQL開發中動態SQL的使用方法(zhuan)

    一般的PL/SQL程序設計中,在DML和事務控制的語句中可以直接使用SQL,但是DDL語句及系統控制語句卻不能在PL/SQL中直接使用,要想實現在PL/SQL中使用DDL語句及系統控制語句,可以通過使用動態SQL來實現。

      首先我們應該了解什么是動態SQL,在Oracle數據庫開發PL/SQL塊中我們使用的SQL分為:靜態SQL語句和動態SQL語句。所謂靜態SQL指在PL/SQL塊中使用的SQL語句在編譯時是明確的,執行的是確定對象。而動態SQL是指在PL/SQL塊編譯時SQL語句是不確定的,如根據用戶輸入的參數的不同而執行不同的操作。編譯程序對動態語句部分不進行處理,只是在程序運行時動態地創建語句、對語句進行語法分析并執行該語句。

      Oracle中動態SQL可以通過本地動態SQL來執行,也可以通過DBMS_SQL包來執行。下面就這兩種情況分別進行說明:

      一、本地動態SQL
      本地動態SQL是使用EXECUTE IMMEDIATE語句來實現的。

      1、本地動態SQL執行DDL語句:
      需求:根據用戶輸入的表名及字段名等參數動態建表。
    create or replace procedure proc_test
      (
      table_name in varchar2, --表名
      field1 in varchar2, --字段名
      datatype1 in varchar2, --字段類型
      field2 in varchar2, --字段名
      datatype2 in varchar2 --字段類型
      ) as
      str_sql varchar2(500);
      begin
      str_sql:=’create table ’||table_name||’(’||field1||’ ’||datatype1||’,’||field2||’ ’||datatype2||’)’;
      execute immediate str_sql; --動態執行DDL語句
      exception
      when others then
      null;
      end ;
      以上是編譯通過的存儲過程代碼。下面執行存儲過程動態建表。  

    SQL> execute proc_test(’dinya_test’,’id’,’number(8) not null’,’name’,’varchar2(100)’);
      PL/SQL procedure successfully completed
      SQL> desc dinya_test;
      Name Type Nullable Default Comments
      ---- ------------- -------- ------- --------
      ID NUMBER(8)
      NAME VARCHAR2(100) Y
      SQL>

      到這里,就實現了我們的需求,使用本地動態SQL根據用戶輸入的表名及字段名、字段類型等參數來實現動態執行DDL語句。

      2、本地動態SQL執行DML語句。
      需求:將用戶輸入的值插入到上例中建好的dinya_test表中。  
    create or replace procedure proc_insert
      (
      id in number, --輸入序號
      name in varchar2 --輸入姓名
      ) as
      str_sql varchar2(500);
      begin
      str_sql:=’insert into dinya_test values(:1,:2)’;
      execute immediate str_sql using id,name; --動態執行插入操作
      exception
      when others then
      null;
      end ;
      執行存儲過程,插入數據到測試表中。
      SQL> execute proc_insert(1,’dinya’);
      PL/SQL procedure successfully completed
      SQL>select * from dinya_test;
      ID NAME
      1 dinya
      在上例中,本地動態SQL執行DML語句時使用了using子句,按順序將輸入的值綁定到變量,如果需要輸出參數,可以在執行動態SQL的時候,使用RETURNING INTO 子句,如: 
    declare
      p_id number:=1;
      v_count number;
      begin
      v_string:=’select count(*) from table_name a where a.id=:id’;
      execute immediate v_string into v_count using p_id;
      end ;
      更多的關于動態SQL中關于返回值及為輸出輸入綁定變量執行參數模式的問題,請讀者自行做測試。

      二、使用DBMS_SQL包
      使用DBMS_SQL包實現動態SQL的步驟如下:A、先將要執行的SQL語句或一個語句塊放到一個字符串變量中。B、使用DBMS_SQL包的parse過程來分析該字符串。C、使用DBMS_SQL包的bind_variable過程來綁定變量。D、使用DBMS_SQL包的execute函數來執行語句。

      1、使用DBMS_SQL包執行DDL語句
      需求:使用DBMS_SQL包根據用戶輸入的表名、字段名及字段類型建表。
    create or replace procedure proc_dbms_sql
      (
      table_name in varchar2, --表名
      field_name1 in varchar2, --字段名
      datatype1 in varchar2, --字段類型
      field_name2 in varchar2, --字段名
      datatype2 in varchar2 --字段類型
      )as
      v_cursor number; --定義光標
      v_string varchar2(200); --定義字符串變量
      v_row number; --行數
      begin
      v_cursor:=dbms_sql.open_cursor; --為處理打開光標
      v_string:=’create table ’||table_name||’(’||field_name1||’ ’||datatype1||’,’||field_name2||’ ’||datatype2||’)’;
      dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析語句
      v_row:=dbms_sql.execute(v_cursor); --執行語句
      dbms_sql.close_cursor(v_cursor); --關閉光標
      exception
      when others then
      dbms_sql.close_cursor(v_cursor); --關閉光標
      raise;
      end;

      以上過程編譯通過后,執行過程創建表結構:

    SQL> execute proc_dbms_sql(’dinya_test2’,’id’,’number(8) not null’,’name’,’varchar2(100)’);
      PL/SQL procedure successfully completed
      SQL> desc dinya_test2;
      Name Type Nullable Default Comments
      ---- ------------- -------- ------- --------
      ID NUMBER(8)
      NAME VARCHAR2(100) Y
      SQL>

      2、使用DBMS_SQL包執行DML語句
      需求:使用DBMS_SQL包根據用戶輸入的值更新表中相對應的記錄。

      查看表中已有記錄: 

    SQL>select * from dinya_test2;
      ID NAME
      1 Oracle
      2 CSDN
      3 ERP
      SQL>

    建存儲過程,并編譯通過:  

    create or replace procedure proc_dbms_sql_update
      (
      id number,
      name varchar2
      )as
      v_cursor number; --定義光標
      v_string varchar2(200); --字符串變量
      v_row number; --行數
      begin
      v_cursor:=dbms_sql.open_cursor; --為處理打開光標
      v_string:=’update dinya_test2 a set a.name=:p_name where a.id=:p_id’;
      dbms_sql.parse(v_cursor,v_string,dbms_sql.native); --分析語句
      dbms_sql.bind_variable(v_cursor,’:p_name’,name); --綁定變量
      dbms_sql.bind_variable(v_cursor,’:p_id’,id); --綁定變量
      v_row:=dbms_sql.execute(v_cursor);            --執行動態SQL
      dbms_sql.close_cursor(v_cursor); --關閉光標
      exception
      when others then
      dbms_sql.close_cursor(v_cursor); --關閉光標
      raise;
      end;
      執行過程,根據用戶輸入的參數更新表中的數據:  

    SQL> execute proc_dbms_sql_update(2,’csdn_dinya’);
      PL/SQL procedure successfully completed
      SQL>select * from dinya_test2;
      ID NAME
      1 Oracle
      2 csdn_dinya
      3 ERP
      SQL>
     
      執行過程后將第二條的name字段的數據更新為新值csdn_dinya。這樣就完成了使用dbms_sql包來執行DML語句的功能。

      使用DBMS_SQL中,如果要執行的動態語句不是查詢語句,使用DBMS_SQL.Execute或DBMS_SQL.Variable_Value來執行,如果要執行動態語句是查詢語句,則要使用DBMS_SQL.define_column定義輸出變量,然后使用DBMS_SQL.Execute, DBMS_SQL.Fetch_Rows, DBMS_SQL.Column_Value及DBMS_SQL.Variable_Value來執行查詢并得到結果。

      總結說明:

      在Oracle開發過程中,我們可以使用動態SQL來執行DDL語句、DML語句、事務控制語句及系統控制語句。但是需要注意的是,PL/SQL塊中使用動態SQL執行DDL語句的時候與別的不同,在DDL中使用綁定變量是非法的(bind_variable(v_cursor,’:p_name’,name)),分析后不需要執行DBMS_SQL.Bind_Variable,直接將輸入的變量加到字符串中即可。另外,DDL是在調用DBMS_SQL.PARSE時執行的,所以DBMS_SQL.EXECUTE也可以不用,即在上例中的v_row:=dbms_sql.execute(v_cursor)部分可以不要。

    posted on 2007-10-17 08:57 都市淘沙者 閱讀(295) 評論(0)  編輯  收藏 所屬分類: Oracle/Mysql/Postgres/

    主站蜘蛛池模板: 免费高清在线爱做视频| 亚洲色少妇熟女11p| 免费一级毛片免费播放| 24小时在线免费视频| caoporn成人免费公开| 亚洲国产欧洲综合997久久| 亚洲免费中文字幕| 久久亚洲国产精品五月天| 久久亚洲av无码精品浪潮| 日本免费一区二区三区最新vr| 国产四虎免费精品视频| 久久精品无码专区免费东京热| 97国免费在线视频| 国产免费A∨在线播放| 全部在线播放免费毛片| 国产亚洲精品精品精品| 亚洲欧美成人综合久久久| 亚洲国产激情在线一区| 亚洲一区二区三区久久久久| 亚洲精品影院久久久久久| 亚洲视频网站在线观看| 亚洲国产一区国产亚洲| 亚洲国产老鸭窝一区二区三区| 亚洲精品国产精品乱码不99| 亚洲人成图片小说网站| 亚洲中文字幕无码久久2017| 国产成人亚洲综合无码| 亚洲人成色7777在线观看不卡| 亚洲国产成人精品女人久久久| 免费看一级做a爰片久久| 又粗又大又长又爽免费视频| 亚洲av无码国产精品色在线看不卡 | 色噜噜的亚洲男人的天堂| 亚洲字幕AV一区二区三区四区| 麻豆狠色伊人亚洲综合网站| 一本天堂ⅴ无码亚洲道久久| 亚洲国产精品无码久久久秋霞1| 色偷偷亚洲第一综合网| 午夜免费国产体验区免费的| 中国精品一级毛片免费播放| 国产情侣久久久久aⅴ免费|