首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >将查询结果插入由变量命名的表中

将查询结果插入由变量命名的表中
EN

Stack Overflow用户
提问于 2013-08-21 17:45:52
回答 2查看 300关注 0票数 0

我有一个存储过程,它运行许多查询并获得许多值,并将其存储在变量中。我希望这个过程能够将查询结果插入到用户提供的表中。我会将给定的表名存储为varchar参数,但是如何将其插入到这个表中呢?

在编译时,Oracle表示该表不存在。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-21 18:36:25

据推测,它是在告诉您使用的变量名称的表不存在,当然不存在。实际的表在编译时可能存在,也可能不存在;因为它是灵活的,所以假设它可能不存在可能更安全。无论哪种方式,您都不知道会发生什么,因此需要使用动态SQL来实现这一点。

正如对另一个答案的注释中提到的,您必须小心SQL注入。通常,您希望在动态SQL中使用绑定变量,但不能将绑定用于对象名称,因此必须将其连接起来。希望您使用的是11g,其中包括dbms_assert包。

下面是一个简单的例子:

代码语言:javascript
代码运行次数:0
运行
复制
create or replace procedure p42 (table_name varchar2) as
begin
  execute immediate 'insert into '
    || dbms_assert.qualified_sql_name(table_name)
    || ' select * from dual';
end;
/

然后,我可以在该过程已经存在之后创建一个表,并成功地调用该过程:

代码语言:javascript
代码运行次数:0
运行
复制
create table t42 (dummy varchar2(1));

exec p42('t42');

select * from t42;

DUMMY
-----
X     

您的真正查询显然要复杂得多,并且应该将绑定变量与目标表名称一起用于传递的任何筛选值。

dbms_assert调用的优点是,如果传入一些非法的内容,并且传递了一些令人讨厌的东西,它就会出错:

代码语言:javascript
代码运行次数:0
运行
复制
exec p42('t42 select ''Y'' from dual union all');

ORA-44004: invalid qualified SQL name
ORA-06512: at "SYS.DBMS_ASSERT", line 207
ORA-06512: at "STACKOVERFLOW.P42", line 3
ORA-06512: at line 1

如果过程只是连接传递的值:

代码语言:javascript
代码运行次数:0
运行
复制
  execute immediate 'insert into ' || table_name || ' select * from dual';

..。然后,相同的调用将在表中插入两行:

代码语言:javascript
代码运行次数:0
运行
复制
exec p42('t42 select ''Y'' from dual union all');

select * from t42;

DUMMY
-----
Y     
X

如果数据完整性对您来说是很重要的话,这是值得担心的事情。如果您不能使用dbms_assert,那么您可以尝试检查传入的名称是否确实存在于all_tables中,并且不包含任何类似于union之类的内容,但更安全的做法是,您不会考虑所有可能的攻击,并让内置函数为您做艰苦的工作。

票数 5
EN

Stack Overflow用户

发布于 2013-08-21 17:51:09

试着做这样的事情:

代码语言:javascript
代码运行次数:0
运行
复制
exec ('insert into ' + @tblname + ' (col) values (123)')
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18364280

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档