Oracle中執行動態SQL

來源:互聯網
上載者:User
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)部分可以不要。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.