如何在oracle脚本中使用变量作为表名

kyxcudwk  于 2023-04-05  发布在  Oracle
关注(0)|答案(5)|浏览(348)

我有一个pl\sql脚本,我想将脚本中使用的表名设置为变量。因此,从我在网上找到的一些示例中,我编写了以下代码。第一部分工作,所以我认为我的一般语法是正确的,但第二部分,我试图将变量用于表名它错误(“*SQL错误:ORA-00903:无效的表名 *”)。
有人知道我做错了什么吗?我不怎么使用PL\SQL,所以可能我只是遗漏了一些明显的东西。

--works
variable numOfrecords number;
exec :numOfrecords := 10;
select * from customers2008 where rownum < :numOfrecords;

--does not work
 variable tableNm CHAR;
 exec :tableNm := 'customers2008';
 print tableNm;
 select * from :tableNm;
ioekq8ef

ioekq8ef1#

如果你从sqlplus运行这个脚本(看起来是这样的),你想使用DEFINE命令,它允许你创建sqlplus替换变量,这些变量只是简单的字符串替换,例如:

define tableNm = 'customers2008'
select * from &tableNm;

有关如何使用这些变量的详细信息,请参阅使用Sql*Plus。您可以使用预定义的位置替换变量从命令行将值传递到脚本中,如下所示:

define tableNm = &1
select * from &tableNm;

...然后像这样调用sqlplus:

sqlplus user/pwd@server @myscript.sql customers2008

如果您没有在命令行中传入值,则会提示脚本调用程序输入该值。
请参阅下面Dave Costa的答案,了解绑定变量和替换变量之间的差异。

nwsw7zdq

nwsw7zdq2#

试着补充一些解释:
您尝试使用的方法称为 bind variable。在Oracle SQL中,绑定变量由冒号后跟标识符来标识。绑定变量的用途是在分析SQL语句时不需要知道其值;语句可以被解析一次,然后使用绑定到变量的不同值执行多次。
为了解析SQL语句,必须知道所涉及的表名和列名。因此,表名不能用绑定变量表示,因为在解析时不知道值。
如果你只是通过SQLPlus执行SQL和内联PL/SQL,那么替换变量是处理这个问题的一个简单方法,正如Steve解释的那样。当SQLPlus客户端读取命令时,替换变量被替换为它的值,甚至在它将命令发送到Oracle进行解析之前。

yyhrrdl8

yyhrrdl83#

你必须这样做:

EXECUTE IMMEDIATE 'select * from ' || tableNm;

这是因为Oracle不允许为表(或任何其他对象名称)绑定变量。
EXECUTE IMMEDIATE方法具有重要的安全含义:当tableNm值是用户提供的时,SQL injection攻击就大行其道了。

j8yoct9x

j8yoct9x4#

替换变量的工作原理:

SQL> select * from &table_name;
Enter value for table_name: dual
old   1: select * from &table_name
new   1: select * from dual

D
-
X
5ssjco0h

5ssjco0h5#

如果您使用SQL Developer,则:

VARIABLE tableNm CHAR;
VARIABLE cur     REFCURSOR;
EXEC :tableNm := 'customers2008';

DECLARE
  v_sql VARCHAR2(200) := 'SELECT * FROM ' || DBMS_ASSERT.QUALIFIED_SQL_NAME(:tableNm);
BEGIN
  OPEN :cur FOR v_sql;
END;
/

PRINT :cur

相关问题