c# - 在 ado.net DBParameter 中将数组作为值传递

标签 c# sql-server oracle ado.net

我正在处理的项目有很多 IN 查询,例如:

SELECT something, anotherthing
FROM atable
WHERE something IN (value1, value2, value3)

这是在 IN 部分中具有 3 个参数的查询示例,但可以使用 1 或 2 或 5 或 10 或 ... 参数执行相同的查询。 问题是每个查询在数据库中都有另一个执行计划,这使得它变慢了。

我想像这样查询:

SELECT something, anotherthing
FROM atable
WHERE something IN (@value1, @value2, @value3)

或者这个:

SELECT something, anotherthing
FROM atable
WHERE something IN (@values)

我已经用一些辅助函数完成了第一个查询,但我仍然对每个参数数量有不同的执行计划。这可以用第二个解决。

将数组作为数据库参数传递的最佳方法是什么?我正在使用 Oracle 和 SQL Server,欢迎为它们提供解决方案。

最佳答案

对于 SQL-Server,有两种常用的方法。 要避免的第三个选项是传入一个varchar并将其连接到一个带有IN的动态SQL语句中——这是一个明显的注入(inject)攻击表面。

合理的选择:

  • 传入 varchar 并使用 UDF 在分隔符 ( like in this question ) 上拆分数据,可能是逗号、竖线、制表符等。加入结果:

    SELECT something, anotherthing
    FROM atable a
    INNER JOIN dbo.SplitUDF(@values) udf
            ON udf.Value = a.something
    
  • 使用table-valued-parameter (SQL2008) 直接加入(避免UDF)

关于c# - 在 ado.net DBParameter 中将数组作为值传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1968763/

相关文章:

c# - 从 System.Runtime.InteropServices.Marshal C# 中找不到 GetActiveObject 的定义

sql-server - 同时插入和删除时出现SQL死锁

sql - 如何在一列中加入值? (SQL Server 2008R2)

sql - 在 SQL 查询中匹配部分日期?

java - 从 shell 脚本调用 .jar

c# - CertEnroll::CX509Enrollment::InstallResponse:找不到对象或属性。 0x80092004 (-2146885628)

c# - 从下拉列表调用javascript函数

c# - 如何在不卡住 UI 的情况下连续更新数据网格(或任何其他 UI 控件)?

r - R 中的 ODBC 连接与 Azure Active Directory 密码身份验证

c# - 在没有存储过程的情况下使用 c# 映射 Oracle UDT