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

时间:2009-07-24 19:24:40

标签: sql oracle scripting plsql

我有一个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;

4 个答案:

答案 0 :(得分:14)

如果从sqlplus运行此脚本(看起来是这种情况),则需要使用DEFINE命令,该命令允许您创建只是直接字符串替换的sqlplus子代变量,例如:

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

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

define tableNm = &1
select * from &tableNm;

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

sqlplus user/pwd@server @myscript.sql customers2008

如果未在命令行中传入值,系统将提示脚本调用者输入值。

请参阅Dave Costa在下面的答案,了解绑定和替换变量之间的差异。

答案 1 :(得分:8)

尝试添加一些解释:

您尝试使用的方法称为绑定变量。绑定变量在Oracle SQL中由冒号后跟标识符标识。绑定变量的目的是在解析SQL语句时不需要知道它的值;语句可以解析一次,然后执行多次,并使用绑定到变量的不同值。

为了解析SQL语句,必须知道所涉及的表名和列名。因此,表名不能用绑定变量表示,因为在解析时不会知道该值。

如果你只是通过SQLPlus执行SQL和内联PL / SQl,那么替换变量是处理这个问题的一种简单方法,正如史蒂夫解释的那样。当SQLPlus客户端读取命令时,替换变量将替换为其值,然后甚至将其发送到Oracle进行解析。

答案 2 :(得分:7)

你必须做这样的事情:

EXECUTE IMMEDIATE 'select * from' || tableNm;

这是因为Oracle不允许表(或任何其他对象名)的绑定变量。

EXECUTE IMMEDIATE方法存在重大安全隐患:当tableNm值由用户提供时,您可以对SQL injection攻击持开放态度。

答案 3 :(得分:6)

Substitution variables工作:

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

D
-
X