我要问的第一个问题是:这个大约 3000 个值的列表来自哪里?如果它来自另一个表,那么您可以编写如下内容:
SELECT JOB
FROM EMP
WHERE JOB IN (SELECT something FROM some_other_table WHERE ... )
对于这个答案的其余部分,我假设它不在任何地方的数据库中。
理论上可以做你想做的事。有多种方法可以设计包含大量绑定变量的查询。例如,我将编写一个脚本来all_objects
使用 3000 个绑定变量查询数据字典视图。我不打算编写一个包含 3000 个绑定变量的 SQL*Plus 脚本,因此我编写了一个 Python 脚本来生成这个 SQL*Plus 脚本。这里是:
ns = range(1, 9001, 3) # = 1, 4, 7, ..., 8998
# This gets rid of a lot of lines saying 'PL/SQL procedure successfully completed'.
print "SET FEEDBACK OFF;"
print
# Declare the bind variables and give them values.
for i, n in enumerate(ns):
print "VARIABLE X%04d NUMBER;" % i
print "EXEC :X%04d := %d;" % (i, n)
print
query = "SELECT object_name FROM all_objects WHERE"
# Break up the query into lines to avoid SQL*Plus' limit of 2500 characters per line.
chunk_size = 100
for i in range(0, len(ns), chunk_size):
query += "OR object_id IN (" + ",".join( ":X%04d" % j for j in range(i, i + chunk_size) ) + ")\n"
query = query.replace("WHEREOR", "WHERE") + ";\n"
print query
然后我能够运行这个脚本,将它的输出重定向到一个.sql
文件,然后.sql
在 SQL*Plus 中运行那个文件。
您可能会注意到我在上面写了“理论上有可能……”。我把理论上的条款放在那里是有充分理由的。该查询似乎是有效的,我不知道它不应该执行的原因。但是,当我在我的 Oracle 实例(XE 11g Beta)上运行它时,我得到了以下输出:
SQL> @genquery.sql
SELECT object_name FROM all_objects WHERE object_id IN (:X0000,:X0001,:X0002,:X0
003,:X0004,:X0005,:X0006,:X0007,:X0008,:X0009,:X0010,:X0011,:X0012,:X0013,:X0014
,:X0015,:X0016,:X0017,:X0018,:X0019,:X0020,:X0021,:X0022,:X0023,:X0024,:X0025,:X
0026,:X0027,:X0028,:X0029,:X0030,:X0031,:X0032,:X0033,:X0034,:X0035,:X0036,:X003
7,:X0038,:X0039,:X0040,:X0041,:X0042,:X0043,:X0044,:X0045,:X0046,:X0047,:X0048,:
X0049,:X0050,:X0051,:X0052,:X0053,:X0054,:X0055,:X0056,:X0057,:X0058,:X0059,:X00
60,:X0061,:X0062,:X0063,:X0064,:X0065,:X0066,:X0067,:X0068,:X0069,:X0070,:X0071,
:X0072,:X0073,:X0074,:X0075,:X0076,:X0077,:X0078,:X0079,:X0080,:X0081,:X0082,:X0
083,:X0084,:X0085,:X0086,:X0087,:X0088,:X0089,:X0090,:X0091,:X0092,:X0093,:X0094
,:X0095,:X0096,:X0097,:X0098,:X0099)
*
第 1 行的错误:
ORA-03113: 通信通道上的文件结尾
进程 ID:556
会话 ID:137 序列号:29
该ORA-03113
错误表明服务器进程崩溃。
我对此尝试了几种变体:
- 根本不使用绑定变量(即直接将值放入)
- 不使用
IN
列表,即写作SELECT ... FROM all_objects WHERE object_id=:X0000 OR object_id=:X0001 OR ...
,
- 使用 OMG Ponies 的方法,
- 使用 OMG Ponies 的方法而不使用绑定变量,
- 将数据复制
all_objects
到表中,然后进行查询。
以上所有方法都会导致ORA-03113
错误。
当然,我不知道其他版本的 Oracle 是否会遭受这些崩溃的影响(我无权访问任何其他版本),但这并不是好兆头。
编辑:您问是否可以实现类似SELECT JOB FROM EMP WHERE JOB IN (:JOB)
. 对此的简短回答是否定的。SQL*Plus 对该VARIABLE
命令的使用信息如下:
用法:VAR[IABLE] [ [ 数字 | 字符 | 字符 (n [字符|字节]) |
VARCHAR2 (n [CHAR|BYTE]) | NCHAR | NCHAR (n) |
NVARCHAR2 (n) | CLOB | NCLOB | 斑点 | 文件
REFCURSOR | BINARY_FLOAT | BINARY_DOUBLE ] ]
上述所有类型都是单个数据值,REFCURSOR
但 SQL*Plus 似乎仍将其视为单个值。我找不到以这种方式查询返回的数据的REFCURSOR
方法。
所以总而言之,你试图实现的目标几乎肯定是不可能的。我不知道您的最终目标是什么,但我认为您无法使用 SQL*Plus 中的单个查询来实现。