![](/img/trans.png)
[英]Two tables reference each other: How to insert row in an Oracle database?
[英]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.