C# 传递sqlparameter中的值列表,可能是结构化的
是否可以使用SqlDbCommand和SqlParameter在C代码中创建类似的内容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) {
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中指定。