【问题标题】:SQL multiple-value parameter in C#C#中的SQL多值参数
【发布时间】:2021-11-10 04:51:43
【问题描述】:

这就是我所拥有的:

 select *
 from AuditQuestionnaires
 where Companyid = @companyid 
   and RiskTypeID != @RiskIdList[x];

为什么我不能像这样添加参数:

command2.Parameters.Add(new SqlParameter("RiskIdList[x]", RiskIdList[x]));

我正在使用 SQL Server,这是我在 .cs 文件中使用的脚本

【问题讨论】:

  • 首先,这不是有效的 SQL。在 SQL 中,您不能在数据集上使用 !=,而只能在单个值上使用。所以你要找的是risktypeid NOT IN (...)。不幸的是,据我所知,数据集不能用作绑定变量。对于像 PostgreSQL 这样支持数组的 DBMS,这可能会有所不同。您要求的 DBMS 是什么?
  • @Klaus Gütter:我做了一个有根据的猜测并相应地更新了请求:-)
  • 不过,您可以通过一些调整,使用表值参数。

标签: c# sql sql-server


【解决方案1】:

首先,由于您使用的是 SQL Server,因此您不能有一个名为 @RiskTypeId[x] 的参数。它根本不是一个有效的名称。

其次,从 c# 传递参数时,参数名称必须包含初始的“@”。

第三,作为一般规则,构造包含 DataType 的 SQLParameter 要好得多。这意味着不需要猜测,而且猜测偶尔会出错。

第四,在我看来,您想要遍历一个数组。没有什么可以阻止你在 c# 中这样做。您只需像这样创建一个 SqlParameter

command2.Parameters.Add(new SqlParameter { ParameterName = "@RiskTypeId", DBType = DBType.Int32, Value = RiskIDList[x] });

但是我怀疑您真正想做的是将列表发送到 SQL Server。为此,您需要使用User-Defined Table Type。在您的情况下,以下内容就足够了:

CREATE TYPE [dbo].[IdList] AS TABLE ([Id] int);

然后你可以为你的查询定义一个参数:

@RiskTypeIdList IdList READONLY

最后,您必须将数组的内容放入 DataTable。因为这是我经常做的事情,所以我为此工作开设了一个班级:

public class TDataTable<int> : DataTable
{
    public TDataTable(IEnumerable<T> ids) : base()
    {
        Columns.Add("Id", typeof(T));
        var added = new HashSet<T>();
        foreach (T id in ids)
        {
            //ensure unique values
            if (added.Add(id))
            {
                Rows.Add(id);
            }
        }
    }
    public TDataTable() : base()
    {
        Columns.Add("Id", typeof(T));
    }
}

然后你可以像这样传递参数:

command2.Parameters.Add(new SqlParameter { ParameterName = "@RiskTypeIdList", SqlDBType = SqlDBType.Structured, Value = new TDataTable<int>(RiskIDList) });

然后,您可以在您的 SQL 中执行 Thorsten 建议的操作:

WHERE RiskTypeId NOT IN (SELECT Id FROM @RiskTypeIdList)

【讨论】:

  • 提示:如果元素已经存在,HashSet.Add 将返回 false - 因此您可以替换“包含”检查
  • @HansKesting 感谢您的提示!我已经相应地更改了代码。
【解决方案2】:

@Thorsten Kettner,它是一个有效的 SQL 查询,我们可以 != 在 sql 查询中。

command2.Parameters.Add(new SqlParameter("RiskIdList[x]", RiskIdList[x]));

我们不能将“RiskIdList[x]”作为SQL参数传递,我们需要像“RiskIdList”这样传递参数,RiskIdList[x]表示您在运行时传递参数,但查询或存储过程中没有动态参数where 子句。

【讨论】:

  • 所以我在 RiskIdlist 中有值列表,所以我如何给这个语句一个特定的值(我的目的是将列表中的所有值提供给 SQL 语句)
  • 我们可以将表参数传递给 SQL 服务器。在 C# 中,我们可以发送 DataTable,在 SQL 中,我们可以使用 Table-Value 参数作为 CREATE TYPE LessonType AS TABLE (RiskId INT)。更多Table-Value参数请访问sqlshack.com/table-valued-parameters-in-sql-server
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多