C#调用SQL Server存储过程仅更新varchar字段首字符问题
问题排查与解决
问题根源
C#代码中参数类型与SQL存储过程参数类型不匹配:
- 存储过程里
@text和@jsonstr定义为**nvarchar(max)**(Unicode类型) - 但C#代码添加参数时使用了**
SqlDbType.VarChar**(非Unicode类型)
.NET中的string默认是Unicode编码,当把Unicode字符串绑定到非Unicode的VarChar参数传递给SQL Server时,会触发隐式类型转换,导致字符串被意外截断,仅保留第一个字符。而SSMS直接执行时参数类型匹配,所以没有问题。
解决方案
任选以下一种方案修复类型不匹配问题:
方案1:修改C#代码的参数类型
将@jsonstr和@text的参数类型改为SqlDbType.NVarChar,与存储过程的nvarchar(max)对应:
try { using (var conn = new SqlConnection(connectionString)) using (var command = new SqlCommand("deepstoredProc", conn) { CommandType = CommandType.StoredProcedure }) { command.Parameters.Add("@recid", SqlDbType.Int).Value = Int32.Parse(recid); // 修改此处参数类型为NVarChar command.Parameters.Add("@jsonstr", SqlDbType.NVarChar, -1).Value = jsonstr; command.Parameters.Add("@text", SqlDbType.NVarChar, -1).Value = txt; conn.Open(); command.ExecuteNonQuery(); } } catch(Exception e) { WriteToSysLog("Exception execSP() " + e.Message); } finally { }
方案2:修改存储过程的参数类型
如果业务不需要Unicode支持,将存储过程的参数改为varchar(max),与C#代码的SqlDbType.VarChar匹配:
USE [testDatabase] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO ALTER PROCEDURE [dbo].[deepstoredProc] @recid int, -- 修改此处参数类型为varchar(max) @jsonstr varchar(max), @text varchar(max) AS BEGIN UPDATE table1 SET transcript = @text, field1 = 'Y' WHERE recordingid = @recid INSERT INTO othertable VALUES (@recid, '', 'textvalue1', COMPRESS(@jsonstr), 'en') INSERT INTO othertable VALUES (@recid, '', 'textvalue2', COMPRESS(@text), 'en') END
额外验证建议
- 确认C#中的
txt变量在传递前是完整的字符串,未被提前截断 - 在SSMS中测试时,使用与C#代码完全相同的参数值,确保测试条件一致
内容的提问来源于stack exchange,提问作者Genius86
相关产品推荐
相关产品推荐

