【发布时间】:2014-10-13 15:18:42
【问题描述】:
我们有一个 C# 组件,用于处理将任意大小的元素列表附加到 IN 子句中,以进行半任意 SQL SELECT 查询。本质上,这归结为收到以下内容:
SELECT COUNT(*) FROM a WHERE b IN (...)
...其中“...”是组件被允许修改的唯一查询部分。
当前组件会插入一组逗号分隔的命名绑定参数,然后将对应的 IDbDataParameter 对象附加到命令并执行;组件知道它必须绑定的参数的类型。这很有效,直到调用代码提供的参数集大于数据库愿意接受的参数集。这里的目标是通过 ODP.NET 让如此大的集合处理针对 Oracle 11gR2 的查询。
由于以下方法被设置要求的人认为是不可接受的,因此这项任务有些复杂:
- 全局临时表
- 存储过程
- 任何需要
CREATE TYPE的事情都已被执行
解决这个问题不需要只执行一个查询。
我正在尝试通过将子句绑定为数组来完成这项工作,使用来自其他地方的代码:
IList<string> values;
//...
OracleParameter parameter = new OracleParameter();
parameter.ParameterName = "parm";
parameter.DbType = DbType.String;
parameter.Value = values.ToArray();
int[] sizes = new int[values.Count];
for (int index = 0; index < values.Count; index++)
{
sizes[index] = values[index].Length;
}
parameter.ArrayBindSize = sizes;
//...
该命令随后执行而没有引发异常,但 COUNT 返回的值为零(与预期值相比,在 SQLDeveloper 中运行查询并使用嵌套的SELECT 返回相同的参数集)。到目前为止,浏览 ODP.NET 文档并没有带来任何乐趣。
对此的问题是:
- 有没有办法使上述参数附件按预期工作?
- 是否有另一种可行的方法来实现这一目标而不使用其中一种被否决的方法?
(我知道这类似于this (unanswered) question,但该场景并未提及对方法有相同的限制。)
【问题讨论】:
-
您是否尝试过使用匿名 PL/SQL 块(例如在 BEGIN 和 END 之间)?它基本上是存储过程代码,只是它位于客户端,而不是存储在服务器中,因此您可以作为开发人员控制它。
-
你是说你达到了参数数量的限制吗?或者是 SQL 的大小?你能分享你得到的 ORA 错误吗?
-
如果不尝试更改,它会得到:ORA-01795:列表中的最大表达式数为 1000
-
此链接中有一些建议的解决方法。它们中的任何一个都适用于你吗? stackoverflow.com/questions/17842453/…
-
网上有几十个涉及 ORA-01795 的问题,它们都涉及以违反此问题中给出的要求的方式重新格式化 SQL。所以我最好的猜测是没有答案,并且 T2PS 将需要阻止向他提供 SQL 的人员或限制他修改它以添加多个“或 where”子句。如果您真的很绝望,请尝试在 OTN SQL 论坛上提出这个问题,在与此问题相同的论坛中:community.oracle.com/thread/235143