带有DECLARE和UPDATE的SqlCommand

时间:2018-09-04 07:18:04

标签: c# sql sql-server

我们有一个旧式数据库,其中一些ID列表以逗号分隔的字符串存储。我需要将其中一个ID替换为其他值。

更具体地说,关注表包含一列,其值类似于“ 1,2,42,100”。请注意,这是一个ID列表,以逗号分隔。 [我知道这不是最好的解决方案,但它是在上世纪中叶摆在我们面前的。]

为此,我有一个在SQL Server中测试过的查询:

declare @w nvarchar(252)
update TableName
  set @w = replace(',' + ColumnName + ',', ',@oldName,', ',@newName,'), ColumnName = substring(@w, 2, len(@w) - 2)

这在SQL Management Studio中有效,但是将其直接转换为C#代码不会产生任何结果:

using (SqlCommand command = connection.CreateCommand())
{
    command.CommandTimeout = Connection.Instance.ConnectionTimeout;
    command.Connection.Open();
    command.CommandText = @"
        declare @w nvarchar(252);
        update TableName
            set @w = replace(',' + ColumnName + ',', ',@oldName,', ',@newName,'), ColumnName = substring(@w, 2, len(@w) - 2)
        <where clause here of course>;";

    SqlParameter param = command.CreateParameter();
    param.ParameterName = "@newName";
    param.Value = newName;
    command.Parameters.Add(param);

    param = command.CreateParameter();
    param.ParameterName = "@oldName";
    param.Value = oldName;
    command.Parameters.Add(param);

    command.ExecuteNonQuery();
    command.Connection.Close();
}

问题是:a)为什么在C#中没有给出错误或期望的结果,以及b)如何解决该问题?

1 个答案:

答案 0 :(得分:1)

感谢所有提供帮助的人!我找到了答案。

事实证明,如果C#和MSSQL不在引号内,则不会将命名参数注入SQL字符串。那正是我的情况。我也说“它在SQL Management Studio中有效”是有点错误的。我没有使用@newName@oldName进行测试,而是将相应的值硬编码到查询中。

所以我的SQL查询确实是:

declare @w nvarchar(252)
update TableName
  set @w = replace(',' + ColumnName + ',', ',42,', ',101,'), ColumnName = substring(@w, 2, len(@w) - 2)

我尝试了确切的查询(在SQL Studio中使用定义的@ newName和@ oldName,但效果不佳。

因此,有效的查询将是:

declare @oldName nvarchar(250)='42'
declare @newName nvarchar(250)='101'
declare @w nvarchar(252)
update RoleMap
  set @w = replace(',' + Argument + ',', ','+@oldName+',', ','+@newName+','), Argument = substring(@w, 2, len(@w) - 2)

请注意,已命名的参数现在是用逗号连接的,而不是用逗号连接的字符串。