如何使用变量在动态查询中指定 IN 子句?
在 PL/SQL 中,您可以使用串联指定 IN 运算符的值:
v_sql := 'select field1
from table1
where field2 in (' || v_list || ')';
是否可以使用变量执行相同的操作?
v_sql := 'select field1
from table1
where field2 in (:v_list)';
如果是这样,怎么办?
编辑:参考Marcin的答案,我如何从结果表中进行选择?
declare
cursor c_get_csv_as_tables is
select in_list(food_list) food_list
from emp_food
where emp_type = 'PERM';
cursor c_get_food_list (v_food_table varchar2Table)is
select *
from v_food_table;
begin
for i in c_get_csv_as_tables loop
for j in c_get_food_list(i.food_list) loop
dbms_output.put_line(j.element);
end loop;
end loop;
end;
我收到以下错误:
ORA-06550: line 10, column 6:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, column 1:
PL/SQL: SQL Statement ignored
ORA-06550: line 15, column 34:
PLS-00364: loop index variable 'J' use is invalid
ORA-06550: line 15, column 13:
PL/SQL: Statement ignored
In PL/SQL, you can specify the values for the IN operator using concatenation:
v_sql := 'select field1
from table1
where field2 in (' || v_list || ')';
Is it possible to do the same using a variable?
v_sql := 'select field1
from table1
where field2 in (:v_list)';
If so, how?
EDIT: With reference to Marcin's answer, how do I select from the resultant table?
declare
cursor c_get_csv_as_tables is
select in_list(food_list) food_list
from emp_food
where emp_type = 'PERM';
cursor c_get_food_list (v_food_table varchar2Table)is
select *
from v_food_table;
begin
for i in c_get_csv_as_tables loop
for j in c_get_food_list(i.food_list) loop
dbms_output.put_line(j.element);
end loop;
end loop;
end;
I get the following error:
ORA-06550: line 10, column 6:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 9, column 1:
PL/SQL: SQL Statement ignored
ORA-06550: line 15, column 34:
PLS-00364: loop index variable 'J' use is invalid
ORA-06550: line 15, column 13:
PL/SQL: Statement ignored
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
就像在@Sathya链接中一样,您可以绑定vararray(我以@Codo为例):
更新:第一个命令可以替换为:
然后调用:
当您添加值时
Like in @Sathya link, you can bind the varray (I took @Codo example):
UPDATE: the first command can be replaced with:
then call:
when ever you add a value
不幸的是,您无法绑定这样的列表,但是您可以使用表函数。阅读此内容
这是一个基于您的代码的用法示例:
我在这里使用了 column_value 伪列
Unfortunately you cannot bind a list like this, however you can use a table function. Read this
Here's an example of usage based on your code:
I used here a column_value pseudocolumn
绑定变量可以在带有“in”子句的 Oracle SQL 查询中使用。
10g 即可工作;我不知道其他版本。
绑定变量是 varchar,最多 4000 个字符。
示例:绑定变量包含以逗号分隔的值列表,例如
:bindvar = 1,2,3,4,5
Bind variable can be used in Oracle SQL query with "in" clause.
Works in 10g; I don't know about other versions.
Bind variable is varchar up to 4000 characters.
Example: Bind variable containing comma-separated list of values, e.g.
:bindvar = 1,2,3,4,5
根据@Marcin的回答,你不能这样做,但是,还有一些需要补充的地方,因为你的查询应该实际工作,即运行。
简而言之,您不能对表或列使用绑定变量。不仅如此,绑定变量被假定为字符,因此如果您想要一个数字,则必须使用 to_number(:b1) 等。
这就是您的查询失败的地方。当您传入一个字符串时,Oracle 假定您的整个列表是单个字符串。因此,您正在有效地跑步:
但是您没有理由不能以不同的方式做到这一点。我假设您正在动态创建
v_list
,这意味着您所需要做的就是以不同的方式创建此列表。据称,一系列or
条件与使用in
没有什么不同:-)。据称,我的意思是永远不要依赖未经测试的东西。尽管 Tom 在链接中确实说可能存在性能限制,但不能保证它不会比开始时使用
in
更快。最好的办法是对您的查询和他的查询运行跟踪,看看有什么区别(如果有)。As per @Marcin's answer you can't do this, however, there's a fair bit to add to that, as your query should actually work, i.e. run.
Simply put, you cannot use a bind variable for a table or column. Not only that, bind variables they are assumed to be a character, so if you want a number you have to use
to_number(:b1)
etc.This is where your query falls down. As you're passing in a string Oracle assumes that your entire list is a single string. Thus you are effectively running:
There is no reason why you can't do this a different way though. I'm going to assume you're dynamically creating
v_list
, which means that all you need to do is create this list differently. A series ofor
conditions is, purportedly :-), no different to using anin
.By purportedly, I mean never rely on something that's untested. Although Tom does say in the link that there may be performance constraints there's no guarantee that it wasn't quicker than using
in
to begin with. The best thing to do is to run the trace on your query and his and see what difference there is, if any.