【发布时间】:2020-06-29 19:42:31
【问题描述】:
我正在尝试创建一个动态查询,以安全地从一个表中选择值并将它们插入到另一个表中,并使用 this_date 作为参数。
因为这将从应用程序外部调用,所以我应该使用绑定变量。
table1 归 Foo 所有。table2 归 Bar 所有。
到目前为止我所拥有的是:
create or replace package body Foo.this_thing
AS
procedure load_this(this_date IN date)
AS
v_select_sql VARCHAR2(255);
type temp_table_type IS TABLE OF Bar.table2$ROWTYPE;
temp_table temp_table_type;
BEGIN
-- Get data from Foo.table1
v_select_sql := 'select :1, field1, field2 from Foo.table1 where field5 = :1';
execute immediate v_select_sql into temp_table using this_date;
-- Load from temp_table into Bar.table2
insert into Bar.table2(attr1, attr2, attr3) select attr1, attr2, attr3 from temp_table;
commit;
END load_this;
END Foo.this_thing;
当我尝试编译它时,出现了这个错误:
错误(101,41):PLS-00597:INTO 列表中的表达式“TEMP_TABLE”类型错误
然后我尝试了这个:
create or replace package body Foo.this_thing
AS
procedure load_this(this_date IN date)
AS
v_sql VARCHAR2(255);
type temp_table_type IS TABLE OF Bar.table2$ROWTYPE;
temp_table temp_table_type;
BEGIN
DBMS_OUTPUT.PUT_LINE('LOAD_THIS:: this_date: ' || to_char(this_date));
v_sql := 'insert into Bar.table2(attr1, attr2, attr3) select :1, field1, field2 from Foo.table1 where field5 = :1';
DBMS_OUTPUT.PUT_LINE('LOAD_THIS:: v_sql set.');
execute immediate v_sql using this_date;
DBMS_OUTPUT.PUT_LINE('LOAD_THIS:: v_sql executed.');
commit;
END load_this;
END Foo.this_thing;
当我执行Foo.this_thing.load_this(TO_DATE('20200629', 'YYYYMMDD')); 时,我在错误消息中得到了这个:
错误报告 -
SQL 错误:ORA-00933:SQL 命令未正确结束
ORA-06512:在“Foo.THIS_THING”,第 102 行
00933. 00000 - “SQL 命令未正确结束”
*原因:
*行动:
LOAD_THIS:: this_date: 29-JUN-20
LOAD_THIS:: v_sql 设置。
错误消息非常模糊,我感觉它与 execeute immediate 命令有关,好像我可能没有正确使用它。
有人知道我错过了什么吗?
【问题讨论】:
-
你为什么要为此使用动态 SQL?
-
@AlexPoole 我正在为此使用动态 SQL,因此我可以保护数据库不成为 SQL 注入的受害者。
-
您不需要在包中使用动态 SQL 来执行此操作。当您在查询中使用传递给过程的参数时,它们实际上是绑定变量。
标签: oracle stored-procedures plsql-package