繁体   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