在 sqlparameter 中传递值列表,可能是结构化的

Pass list of values in sqlparameter, structured perhaps

是否可以使用 SqlDbCommand 和 SqlParameter 在 C# 代码中创建类似的东西?

DECLARE @Users TABLE (ID INT)
INSERT INTO @Users
VALUES (10),(20),(30)

SELECT COUNT(*) FROM @Users

我试过这样的事情:
1) 数据表创建者:

        private static DataTable CreateDataTable(IEnumerable<int> ids)
        {
        DataTable table = new DataTable();
        table.Columns.Add("ID", typeof(int));
        foreach (int id in ids)
        {
            table.Rows.Add(id);
        }
        return table;

2) 添加SqlParameter:

 sqlParameters.Add(new SqlParameter()
                            {
                                ParameterName = $"@paramname",
                                SqlDbType = SqlDbType.Structured,
                                Value = table
                            });

3) 执行命令(命令是 SELECT COUNT(*) FROM @Users),参数是第 2 步中的参数列表:

using (SqlCommand cmd = new SqlCommand(command, connection))
                {
                    if (parameters != null)
                        cmd.Parameters.AddRange(parameters.ToArray());

                    SqlDataReader reader = cmd.ExecuteReader();

我得到的是:

The table type parameter '@Users' must have a valid type name.

而且我真的没有真正的 table 所以没有可用的类型,只是希望它是:

DECLARE @Users TABLE (ID INT)

这可行吗?我想要实现的只是传递值列表,在本例中显然是整数列表。

关于标记为重复:
提供 link 不能解决问题,因为它不是缺少类型名问题,而是缺少要使用的类型名。问题是我无法创建任何 table,也无法使用任何现有的在 SqlParameter 中传递 TypeName。

一个可行的解决方案:

CREATE TYPE [dbo].[IntList] AS TABLE(
[Value] [int] NOT NULL
)

然后是 SqlParameter:

sqlParameters.Add(new SqlParameter()
                        {
                            ParameterName = $"@paramname",
                            SqlDbType = SqlDbType.Structured,
                            Value = table,
                            TypeName = "dbo.IntList"
                        });

尽管如此,另一个步骤是使用 GarethD 建议的内置类型。我不确定它们是否在 SQL Server 2016 中可用。

您需要使用 table 类型参数。首先你需要创建 table 输入 SQL。然后从 C#

传递参数

取数据table作为SP参数

@dt customdatatable READONLY

编写以下 C# 代码

DataTable dt = new DataTable();
dt.Columns.Add("customcolumnname");
DataRow dr = dt.NewRow();
dr["customcolumnname"] = "columnvalue";
dt.Rows.Add(dr);

SqlParameter[] parCollection = new SqlParameter[1];
parCollection[0] = new SqlParameter("@yourdt", dt);

您需要在 sqlParameter 中添加 TypeName ,与您在数据库中创建的 table 类型同名。

 sqlParameters.Add(new SqlParameter()
                            {
                                ParameterName = $"@paramname",
                                SqlDbType = SqlDbType.Structured,
                                Value = table,
                                TypeName = "dbo.MyType";
                            });

如果您没有 table 类型的数据库,那么首先您需要在 SQL

中创建它
CREATE TYPE [dbo].[IntegerList] AS TABLE(
    [Data] [int] NOT NULL,  
)
GO

然后在您的代码中输入该名称。这将起作用,您确实需要为此在数据库中创建 table。