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

C# 传递sqlparameter中的值列表,可能是结构化的,c#,tsql,ado.net,C#,Tsql,Ado.net,是否可以使用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) {

是否可以使用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;
3执行命令命令是从@Users中选择COUNT*,参数是步骤2中的参数列表:

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

                    SqlDataReader reader = cmd.ExecuteReader();
我得到的是:

表类型参数“@Users”必须具有有效的类型名称

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

声明@Users表ID INT

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

对于标记为重复的: 提供的链接并不能解决问题,因为它不是缺少typename问题,而是缺少要使用的typename。问题是我无法创建任何表,也无法使用任何现有表在SqlParameter中传递TypeName

一个可行的解决办法:

然后是SqlParameter:

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

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

您需要使用表类型参数。首先,您需要在SQL中创建表类型。然后从C传递参数

将数据表作为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);

您需要使用表类型参数。首先,您需要在SQL中创建表类型。然后从C传递参数

将数据表作为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,该名称与您在DB中创建的表类型相同

 sqlParameters.Add(new SqlParameter()
                            {
                                ParameterName = $"@paramname",
                                SqlDbType = SqlDbType.Structured,
                                Value = table,
                                TypeName = "dbo.MyType";
                            });
若数据库中并没有表类型,那个么首先需要在SQL中创建它

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

然后在代码中输入该名称。这将起作用,您确实需要为此在DB中创建表。

您需要在sqlParameter中添加TypeName,该名称与您在DB中创建的表类型相同

 sqlParameters.Add(new SqlParameter()
                            {
                                ParameterName = $"@paramname",
                                SqlDbType = SqlDbType.Structured,
                                Value = table,
                                TypeName = "dbo.MyType";
                            });
若数据库中并没有表类型,那个么首先需要在SQL中创建它

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


然后在代码中输入该名称。这将起作用,您确实需要在DB中为此创建表。

链接的答案应该解释如何执行此操作,但总而言之,您必须首先在DB中创建自定义表类型,例如,创建类型dbo.ListOfInt作为表值INT NOT NULL;,然后你可以在代码中使用它们,所以在我的示例中,根本不可能在DECLARE语句中使用它们?这意味着我实际上根本没有db类型,只是声明了TABEL id int?不,这是不可能的,您需要创建表类型,尽管一旦设置这些表类型是可重用的,所以您只需要设置一次类型,以后就可以了。我的大多数数据库都设置了通用表类型dbo.ListOfInt、dbo.ListOfString等。然后这些类型可以在任何地方重复使用。这很有趣,对我来说可能很有用。如果SQL Server 2016中有这些表,您知道在哪里可以找到它们吗?对不起,我不太清楚,这些通用表类型在我的大多数数据库中都有,因为它们不是内置的。它们是其中的一种,有点像日历表,对于许多不同的事情都非常有用,而且开销很小或没有开销,因此也可以与任何数据库一起创建,以防将来需要它们。链接的答案应该解释如何做到这一点,但总而言之,您必须首先在数据库中创建自定义表类型,例如,将类型dbo.ListOfInt创建为表值INT NOT NULL;,然后你可以在代码中使用它们,所以在我的示例中,根本不可能在DECLARE语句中使用它们?这意味着我实际上根本没有db类型,只是声明了TABEL id int?不,这是不可能的,您需要创建表类型,尽管一旦设置这些表类型是可重用的,所以您只需要设置一次类型,以后就可以了。我的大多数数据库都设置了通用表类型dbo.ListOfInt、dbo.ListOfString等。然后这些类型可以在任何地方重复使用。这很有趣,对我来说可能很有用。如果SQL Server 2016中有这些表,您知道在哪里可以找到它们吗?对不起,我不太清楚,这些通用表类型在我的大多数数据库中都有,因为它们不是内置的。它们就是其中之一,有点像一个日历表,对于许多不同的事情都非常有用,开销很小或没有开销,因此也可以与任何数据库一起创建,以防将来需要它们。我根本没有DB类型,所以无法使用它。这是问题的关键所在。@Mike如果没有表类型,那么首先需要创建它。我发现了完全相同的解决方案,我的意思是使用创建类型。这是正确的答案。您确实需要创建用户定义的表类型,但不必在SqlParameter中指定类型名称。我已经尝试过了。它不起作用。如果不显式指定类型名,则会出现与没有用户定义tabl时相同的错误
完全是e型。它必须在SqlParameter中指定。我根本没有DB类型,所以无法使用它。这是问题的关键所在。@Mike如果没有表类型,那么首先需要创建它。我发现了完全相同的解决方案,我的意思是使用创建类型。这是正确的答案。您确实需要创建用户定义的表类型,但不必在SqlParameter中指定类型名称。我已经尝试过了。它不起作用。如果不显式指定类型名,则会出现与没有用户定义的表类型时相同的错误。它必须在SqlParameter中指定。