好吧,既然不允许使用全局临时表,那么至少可以创建普通表吗?如果是这样,这里有一个方法:
使用以下命令文本创建 OracleCommand 对象:
@"BEGIN
CREATE TABLE {inListTableName}
(
inValue {dbDataType}
)
INSERT INTO {inListTableName}(inValue) VALUES(:inValue);
END"
将命令对象上的 ArrayBindCount 设置为列表中所需的项目数。
Replace {inListTableName}
与Guid.NewGuid().ToString()
.
更换{dbDataType}
使用正确的 Oracle 数据类型来表示要在 in 子句中使用的值列表。
将 OracleParameter 添加到名为“inValue”的 OracleCommand 中,并将参数的值设置为包含 in 子句中所需值的数组。如果您有哈希集(我建议使用它以避免发送不必要的重复项),请使用.ToArray()
就可以得到一个数组。
执行这个命令。这是您的准备命令。
然后使用以下 sql 片段作为 select sql 语句中 in 子句的值部分:(SELECT {inListTableName}.inValue FROM {inListTableName})
例如:
SELECT FirstName, LastName FROM Users WHERE UserId IN (SELECT {inListTableName}.inValue FROM {inListTableName});
执行此命令以获取读取器。
最后,还有一个命令,其命令文本如下:
DROP TABLE {inListTableName};
这是您的清理命令。执行这个命令。
您可能想要创建一个备用架构/用户来创建inListTable
这样您就可以向用户授予适当的权限,使其仅在该架构中创建表。
所有这些都可以封装在具有以下接口的可重用类中:
public interface IInListOperation
{
void TransmitValueList(OracleConnection connection);
string GetInListSQLSnippet();
void RemoveValueList();
}
TransmitValueList
将创建您的准备命令,添加参数并执行准备命令。
GetInListSQLSnippet
只会返回(SELECT {inListTableName}.inValue FROM {inListTableName});
RemoveValueList
清理干净。
该类的构造函数将采用值列表和 oracle db 数据类型,并生成inListTableName
.
如果您可以使用全局临时表,我建议您不要创建和删除表。
编辑:
我想补充一点,如果您的条款涉及NOT IN
列表或其他不等式运算符。以下面为例:
SELECT FirstName, LastName FROM Users WHERE Status == 'ACTIVE' OR UserID NOT IN (1,2,3,4,5,6,7,8,9,10);
如果使用拆分的方法NOT IN
分开,你最终会得到无效的结果。以下对上一个示例进行划分的示例将返回所有用户,而不是除 UserId 1-10 之外的所有用户。
SELECT FirstName, LastName FROM Users WHERE UserID NOT IN (1,2,3,4,5)
UNION
SELECT FirstName, LastName FROM Users WHERE UserID NOT IN (6,7,8,9,10);