在 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。
是否可以使用 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。