1

我在表中有一个 NVARCHAR(max) 列和一个存储过程,它将使用 CASE 切换更新此列以及表中的任何其他列:

CREATE PROCEDURE updateTable
   @columnName sysname,
   @value nvarchar(max)
AS 
   UPDATE [dbo].[TestTable]
   SET 
      BigNvarcharValue = CASE @columnName WHEN 'BigNvarcharValue' THEN @value ELSE BigNvarcharValue END,  
      TableName = CASE @columnName WHEN 'TableName' THEN @value ELSE TableName END

如果我从 SQL Management Studio 执行此过程,一切都很好

EXEC [dbo].[updateTable]
     @columnName = 'BigNvarcharValue',
     @value = N'SOME BIG 80Kb value'

我也可以使用相同的存储过程从 C# 代码更新 TableName,但是当从 C# 更新这个 BigNvarcharValue 时,它​​会失败并出现 SQLException ,即“字符串或二进制数据将被截断”。现在,我认为它与此存储过程中的 CASE 有关,因为当我将其分解为更简单的存储过程时,一切正常:

CREATE PROCEDURE updateTable   
     @columnName sysname,   
     @value nvarchar(max)
AS       
   UPDATE [dbo].[TestTable]   
   SET BigNvarcharValue=@value

我阅读了一堆论坛帖子,这些帖子描述了尝试将更大的值插入 NVARCHAR 列的问题,这会导致此异常,但它似乎并不适用。

我对 T-SQL 相当陌生,那么 CASE 有什么我不知道的限制吗?

PS BigNvarcharValue 是 NVARCHAR(MAX) 并且 TableName 是 NVARCHAR(50)

4

4 回答 4

1

该错误本身说明了“字符串或二进制数据将被截断”。这意味着您似乎插入了比nvarchar(max)可以处理的更大的值。

SSMS 2008 具有一些调试功能,允许设置断点等。

我认为您可能希望关注System.String最大容量。这只是某个地方的长度问题。

于 2010-10-26T00:07:24.447 回答
1

您正在处理的列的数据类型是什么?因为我通过尝试将 NVARCHAR(max) 允许的值插入到 VARCHAR(50) 的列中来重现错误。

重申一下 - NVARCHAR(max) 允许您指定一个比所述数据类型长的值,这就是您收到截断错误的原因。

于 2010-10-26T00:14:23.560 回答
1

使用完全相同的存储过程和您描述的表,我运行了以下代码

class Program
    {
    static void Main(string[] args)
    {

        using(SqlConnection cnn = new SqlConnection(@"Server=.;Database=test;Trusted_Connection=True;"))
        {
            cnn.Open();
            SqlCommand cmd = new SqlCommand("updateTable",cnn);
            cmd.CommandType = System.Data.CommandType.StoredProcedure;
            cmd.Parameters.Add(new SqlParameter("@columnName",
                   System.Data.SqlDbType.NVarChar, 128));

            cmd.Parameters["@columnName"].Value = "BigNvarcharValue";

            cmd.Parameters.Add(new SqlParameter("@value",  
                     System.Data.SqlDbType.NVarChar, -1));
            cmd.Parameters["@value"].Value = new string('T', 80000);

            cmd.ExecuteNonQuery();



        }

    }
}

它工作得很好。我会检查命令文本和参数集合(名称和值)并验证每一个都如你所想。

于 2010-10-26T03:27:22.110 回答
0

感谢大家的回复。我最终将大列的更新分离到一个单独的过程中,从而解决了这个问题。我确定罪魁祸首是 CASE 声明。

于 2010-10-27T23:23:37.093 回答