将用户定义的 table 传递给 SqlCommand(不执行存储过程)
Pass a user defined table to a SqlCommand (which doesn't execute a stored procedure)
我正在尝试将用户定义的 table 与简单的 SqlCommand
(不执行存储过程)结合使用。
我收到消息 Must declare the scalar variable
,尽管参数已经定义。
代码(假设accountIds
在别处定义,所以dtAccountIds
有一些值):
var sqlCommand = new SqlCommand();
sqlCommand.CommandText =
@"SELECT * INTO #RecordsToLog
FROM Accounts
WHERE [AccountId] IN (@AccountIds)";
var dtAccountIds = new DataTable();
dtAccountIds.Columns.Add("id", typeof(int));
accountIds.ToList().ForEach(id => dtAccountIds.Rows.Add(id));
sqlCommand.Parameters.AddWithValue("@AccountIds", dtAccountIds).TypeName = "dbo.IdsTable";
sqlCommand.ExecuteNonQuery();
用户定义的 table 创建于:
CREATE TYPE [dbo].[IdsTable] AS TABLE([id] [int] NULL)
我应该怎么做才能解决这个问题?
您必须将参数配置为SqlDbType.Structured
。避免使用 AddWithValue
,让我建议这个符号:
SqlParameter param = new SqlParameter("@AccountIds", SqlDbType.Structured, 0)
{
Value = dtAccountIds
}
根据 MS-DOCS 关于 SqlDbType Enum:
Structured = A special data type for specifying structured data contained in table-valued parameters.
首先,你的SQL代码是错误的。 table参数是一个table变量,所以你需要一个完整的子查询IN (SELECT id FROM @AccountIds)
.
为什么要插入临时文件 table,我不知道,你没有给我们任何上下文。
接下来,you shouldn't use AddWithValue
、 改为声明确切的类型 SqlDbType.Structured
,以及 Direction
和 TypeName
此外,希望您没有缓存连接对象。 您必须释放连接和命令对象。
const string query = @"
SELECT *
INTO #RecordsToLog
FROM Accounts
WHERE [AccountId] IN
(SELECT id FROM @AccountIds)
";
using (var sqlCommand = new SqlCommand(query, connection))
{
var dtAccountIds = new DataTable { Columns = { { "id", typeof(int) } } };
foreach (var id in accountIds)
dtAccountIds.Rows.Add(id);
sqlCommand.Parameters.Add(new SqlParameter("@AccountIds", SqlDbType.Structured)
{
Value = dtAccountIds,
TypeName = "dbo.IdsTable",
Direction = ParameterDirection.Input
});
sqlCommand.ExecuteNonQuery();
}
我正在尝试将用户定义的 table 与简单的 SqlCommand
(不执行存储过程)结合使用。
我收到消息 Must declare the scalar variable
,尽管参数已经定义。
代码(假设accountIds
在别处定义,所以dtAccountIds
有一些值):
var sqlCommand = new SqlCommand();
sqlCommand.CommandText =
@"SELECT * INTO #RecordsToLog
FROM Accounts
WHERE [AccountId] IN (@AccountIds)";
var dtAccountIds = new DataTable();
dtAccountIds.Columns.Add("id", typeof(int));
accountIds.ToList().ForEach(id => dtAccountIds.Rows.Add(id));
sqlCommand.Parameters.AddWithValue("@AccountIds", dtAccountIds).TypeName = "dbo.IdsTable";
sqlCommand.ExecuteNonQuery();
用户定义的 table 创建于:
CREATE TYPE [dbo].[IdsTable] AS TABLE([id] [int] NULL)
我应该怎么做才能解决这个问题?
您必须将参数配置为SqlDbType.Structured
。避免使用 AddWithValue
,让我建议这个符号:
SqlParameter param = new SqlParameter("@AccountIds", SqlDbType.Structured, 0)
{
Value = dtAccountIds
}
根据 MS-DOCS 关于 SqlDbType Enum:
Structured = A special data type for specifying structured data contained in table-valued parameters.
首先,你的SQL代码是错误的。 table参数是一个table变量,所以你需要一个完整的子查询IN (SELECT id FROM @AccountIds)
.
为什么要插入临时文件 table,我不知道,你没有给我们任何上下文。
接下来,you shouldn't use AddWithValue
、 改为声明确切的类型 SqlDbType.Structured
,以及 Direction
和 TypeName
此外,希望您没有缓存连接对象。 您必须释放连接和命令对象。
const string query = @"
SELECT *
INTO #RecordsToLog
FROM Accounts
WHERE [AccountId] IN
(SELECT id FROM @AccountIds)
";
using (var sqlCommand = new SqlCommand(query, connection))
{
var dtAccountIds = new DataTable { Columns = { { "id", typeof(int) } } };
foreach (var id in accountIds)
dtAccountIds.Rows.Add(id);
sqlCommand.Parameters.Add(new SqlParameter("@AccountIds", SqlDbType.Structured)
{
Value = dtAccountIds,
TypeName = "dbo.IdsTable",
Direction = ParameterDirection.Input
});
sqlCommand.ExecuteNonQuery();
}