简体   繁体   English

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

[英]how to use a variable in oracle script for the table name

I have an pl\\sql script where I want to set the table name used in the script to a variable. 我有一个pl \\ sql脚本,我想将脚本中使用的表名设置为变量。 So, from some examples I found on the web, I wrote the code below. 因此,从我在网上找到的一些例子中,我编写了下面的代码。 The first section works, so I think my general syntax is correct,but the second section, where I attempt to use a variable for a table name it errors (" SQL Error: ORA-00903: invalid table name "). 第一部分工作,所以我认为我的一般语法是正确的,但第二部分,我尝试使用一个变量的表名称它错误(“ SQL错误:ORA-00903:无效的表名 ”)。

Anybody know what I'm doing wrong...I don't do a lot of PL\\SQL so maybe I'm just missing something obvious. 有人知道我做错了什么......我没有做很多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;

If you are running this script from sqlplus (which looks to be the case), you want to use the DEFINE command, which allows you to create sqlplus substition variables that are just straight string substitution, eg: 如果从sqlplus运行此脚本(看起来就是这种情况),则需要使用DEFINE命令,该命令允许您创建仅直接字符串替换的sqlplus子代变量,例如:

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

See Using Sql*Plus for more information on how these are used. 有关如何使用它们的更多信息,请参阅使用Sql * Plus You can pass values into your script from the command line using the predefined positional substition variables, like this: 您可以使用预定义的位置替换变量从命令行将值传递到脚本中,如下所示:

define tableNm = &1
select * from &tableNm;

... and then invoke sqlplus like so: ...然后像这样调用sqlplus:

sqlplus user/pwd@server @myscript.sql customers2008

If you don't pass in a value on the command line, the script invoker will be prompted for the value. 如果未在命令行中传入值,则将提示脚本调用程序输入值。

See Dave Costa's answer below for the differences between bind and substitution variables. 有关绑定和替换变量之间的差异,请参阅下面的Dave Costa的答案。

To try to add some explanation: 要尝试添加一些解释:

The method that you were trying to use is called a bind variable . 您尝试使用的方法称为绑定变量 A bind variable is identified in Oracle SQL by a colon followed by an identifier. 绑定变量在Oracle SQL中由冒号后跟标识符标识。 The purpose of a bind variable is that its value does not need to be known when parsing the SQL statement; 绑定变量的目的是在解析SQL语句时不需要知道它的值; the statement can be parsed once and then executed multiple times with different values bound to the variable. 语句可以解析一次,然后执行多次,并使用绑定到变量的不同值。

In order for a SQL statement to be parsed, the table and column names involved must be known. 为了解析SQL语句,必须知道所涉及的表名和列名。 So the table name can't be represented by a bind variable, because the value would not be known at parse time. 因此,表名不能由绑定变量表示,因为在解析时不会知道该值。

If you are simply executing SQL and inline PL/SQl via SQLPlus, then substitution variables are an easy way to deal with this issue, as Steve explained. 如果你只是通过SQLPlus执行SQL和内联PL / SQl,那么替换变量是处理这个问题的一种简单方法,正如史蒂夫解释的那样。 A substitution variable is replaced with its value when the SQLPlus client reads the command, before it even sends it to Oracle for parsing. 当SQLPlus客户端读取命令时,替换变量将替换为其值,甚至在将其发送到Oracle进行解析之前。

You have to do something like this: 你必须做这样的事情:

EXECUTE IMMEDIATE 'select * from' || tableNm;

This is because Oracle does not allow bind variables for table (or any other object names). 这是因为Oracle不允许表(或任何其他对象名称)的绑定变量。

There are significant security implications with the EXECUTE IMMEDIATE approach: when the tableNm value is user-supplied, you are wide open to SQL injection attacks. 使用EXECUTE IMMEDIATE方法会产生重大的安全隐患:当tableNm值是用户提供的时,您对SQL注入攻击持开放态度。

Substitution variables work: 替换变量有效:

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

D
-
X

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM