Oracle

當變數的確切數量未知時如何在“動態查詢”中使用“綁定變數”

  • August 1, 2020

我有一個正在使用Dynamic SQL(variable actual_query) 的過程,我正在根據輸入參數生成這個查詢,輸入參數i_tables是一些表的名稱的串聯。它具有以下形式之一:

  1. 所有表`test_table1,test_table2。
  2. 沒有。所以NULL將傳遞給程序。

我已經閱讀了Bind variable它在預防injection和改善方面的重要作用performance,我想在我的程序中使用它。問題是我不知道我應該如何更改我的程序以在這種情況下特別使用它們,number of variables are not known.當你知道變數的確切數量,您編寫execute immediate actual_query using var1,var2並且您知道您將有 2 個變數。

create or replace procedure bind_variable_test(i_tables varchar2,
                                              i_cid    number,
                                              o_result out sys_refcursor) is
actual_query varchar2(1000) := '';
begin

-- this is the base query   
actual_query := 'select * 
           from z_test_a t1 
             inner join z_test_b t2 
              on t1.id = t2.id';
           
-- check input parameter " i_tables "   
if i_tables like '%test_table1%' then
 actual_query := actual_query || ' ' || 'inner join test_table1 t3 on ' ||
                    't3.id = t1.id ' || 'and t3.cid = ' || i_cid;
end if;

if i_tables like '%test_table2%' then
 actual_query := actual_query || ' ' || 'inner join test_table2 t4 on ' ||
                    't4.id = t1.id ' || 'and t4.cid = ' || i_cid;
end if;


-- debug results
dbms_output.put_line(actual_query); 

-- execute    
open o_result for actual_query;
end;

閱讀DBMS_SQL手冊後,我嘗試編輯我的程式碼,我這樣做了:

create or replace procedure z_bind_variable_test(i_tables varchar2,
                                            i_cid    number,
                                            o_result out sys_refcursor)       is
actual_query varchar2(1000) := '';
c            pls_integer;
begin
-- this is the base query
actual_query := 'select * 
             from z_test_a t1 
              inner join z_test_b t2  
           on t1.c_num = t2.c_num ';

-- check input parameter " i_tables "
if i_tables like '%test_table1%' then
 actual_query := actual_query || ' ' || 'inner join test_table1 t3 ' ||
               'on t3.C_NUM = t1.C_NUM ' || 'and t3.cid = :c_id';
end if;

if i_tables like '%test_table2%' then
 actual_query := actual_query || ' ' || 'inner join test_table2 t4 ' ||
               'on t4.C_NUM = t1.C_NUM ' || 'and t4.cid = :c_id ';
end if;

-- get cursor
c := dbms_sql.open_cursor();

-- parse the SQL
dbms_sql.parse(c, actual_query, DBMS_SQL.NATIVE);

-- using bind variables
dbms_sql.bind_variable(c, ':c_id', i_cid);

-- execute
o_result := dbms_sql.execute(c);

-- close the cursor
dbms_sql.close_cursor(c);
end;

但它只是行不通!我想學習如何正確使用綁定變數,但不知道我是否走對了路。

更新:我得到的錯誤是PLS-00382:Expression is of wrong type。問題在於這部分o_result := dbms_sql.execute(c);

使用DBMS_SQL.

精美的手冊有很多例子。

樣本

待定

拆分變數並獲取每個元素。也就是說,使用游標

引用自:https://dba.stackexchange.com/questions/271701