是否可以使用SqlDbCommand和SqlParameter在C#代码中创建类似的内容?
DECLARE @Users TABLE (ID INT)
INSERT INTO @Users
VALUES (10),(20),(30)
SELECT COUNT(*) FROM @Users
我尝试过这样的事情:
1)DataTable创建者:
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();
我得到的是:
表类型参数'@Users'必须具有有效的类型名称。
我真的没有真正的表,所以没有可用的类型,只是希望它是
声明@Users表(ID INT)
那可行吗?我要实现的只是传递值列表,显然是这种情况下的整数列表。
要标记为重复项:
提供的链接不能解决问题,因为它不是缺少typename问题,而是缺少要使用的typename。问题是我无法创建任何表,也无法使用任何现有的表在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中是否可用。
答案 0 :(得分:1)
您需要使用表类型参数。首先,您需要在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);
答案 1 :(得分:1)
您需要在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
然后在代码中输入该名称。那将起作用,并且您确实需要为此在数据库中创建表。