簡體   English   中英

如何在兩個表相互依賴的兩個表中創建動態插入? (Oracle SQL)

[英]How can i create a dynamic insert into two tables where both tables depend on each other? (oracle sql)

我必須創建一個過程,在其中可以對兩個表進行兩次插入-動態進行。

這兩個表相互依賴。

我的想法像這樣:

create or replace PROCEDURE INSERT_DYN( 
  par_table_name_a IN STRING, 
  par_keys_a IN ARRAY, 
  par_values_a IN ARRAY,

  par_table_name_b IN STRING, 
  par_keys_b IN ARRAY, 
  par_values_b IN ARRAY)
AS
BEGIN
  INSERT INTO par_table_name_a(par_keys_a) VALUES(par_values_a);
  INSERT INTO par_table_name_b(par_keys_b) VALUES(par_values_b);

 commit;
END INSERT_DYN;

但是沒有像“數組”這樣的簡單類型可以在其中放置數字,日期,字符串或鍵。

我怎么解決這個問題?

檢查Package DBMS_SQL,在其中找到所有過程。 這是一個未經測試的示例:

CREATE OR REPLACE TYPE VARCHAR_TABLE_TYPE AS TABLE OF VARCHAR2(1000);

create or replace PROCEDURE INSERT_DYN( 
  par_table_name_a IN VARCHAR2, 
  par_keys_a IN VARCHAR_TABLE_TYPE, 
  par_values_a IN VARCHAR_TABLE_TYPE) as

cur INTEGER;
res INTEGER;
sqlcmd VARCHAR2(10000);

begin

sqlcmd := 'INSERT INTO '||par_table_name_a||' (';
FOR i in par_keys_a.first..par_keys_a.last loop
   sqlcmd := sqlcmd ||par_keys_a(i)||',';
end loop;
sqlcmd := REGEXP_REPLACE(sqlcmd, ',$', ')');

sqlcmd := sqlcmd||' values ('
FOR i in par_keys_a.first..par_keys_a.last loop
   sqlcmd := sqlcmd ||':b'||i||',';
end loop;
sqlcmd := REGEXP_REPLACE(sqlcmd, ',$', ')');

-- Check if command is properly composed:
DBMS_OUTPUT.PUT_LINE(sqlcmd);

cur := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(cur, sqlcmd, DBMS_SQL.NATIVE);
FOR i in par_keys_a.first..par_keys_a.last loop
    DBMS_SQL.BIND_VARIABLE(cur, ':b'||i, par_values_a(i));
END LOOP;
res := DBMS_SQL.EXECUTE(cur);
DBMS_SQL.CLOSE_CURSOR(cur);

end;

一個數組(在Oracle中稱為“嵌套表”)僅包含相同數據類型的元素,這里我使用VARCHAR2。 對於NUMBER類型的值,使用相同的嵌套表沒有問題。 對於DATE或類似的值,您必須做一些技巧,例如使用某種模式和正則表達式,或提供另一個嵌套表,其中包含每個字段的數據類型。

另一個解決方案是跳過綁定變量並進行硬解析,即替換此

sqlcmd := sqlcmd||' values ('
FOR i in par_keys_a.first..par_keys_a.last loop
   sqlcmd := sqlcmd ||':b'||i||',';
end loop;
sqlcmd := REGEXP_REPLACE(sqlcmd, ',$', ')');
...
END;

通過這個

sqlcmd := sqlcmd||' values ('
FOR i in par_keys_a.first..par_keys_a.last loop
   sqlcmd := sqlcmd ||''''||par_values_a(i)||''',';
end loop;
sqlcmd := REGEXP_REPLACE(sqlcmd, ',$', ')');
EXECUTE IMMEDIATE sqlcmd;
END;

但是,這為SQL注入打開了大門,您仍然會遇到VARCHAR或NUMBER以外的其他數據類型的問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM