ASP.NET Core 2调用MS SQL存储过程出现排序规则冲突报错求助
解决SQL Server排序规则冲突问题:C#调用存储过程报错但SSMS正常的处理方法
这个问题的核心原因是C#客户端传入的参数排序规则和存储过程中涉及的数据库字段排序规则不匹配——SSMS执行时参数会继承当前数据库的默认排序规则,而SqlClient在C#中默认可能用的是SQL_Latin1_General_CP1_CI_AS,和你数据库里的Cyrillic_General_CI_AS冲突,导致字符串比较操作报错。下面是几个可行的解决办法:
1. 在C#中显式指定参数的排序规则
不要用匿名类型传递参数,改用SqlParameter对象手动指定参数的排序规则,匹配存储过程中字段的排序规则:
// 构造参数数组 var parameters = new List<SqlParameter> { new SqlParameter("@Prc_ID", input.Prc_ID), new SqlParameter("@Cust_ID", input.Cust_ID), new SqlParameter("@AppCode", SqlDbType.NVarChar) { Value = input.AppCode, // 这里设置为存储过程中用到的字段的排序规则 Collation = "Cyrillic_General_CI_AS" } }; // 执行查询 res = db.Query<SearchPictureInfoOutputModel>( "sp_SearchPictureInfo", parameters.ToArray(), commandType: CommandType.StoredProcedure ).FirstOrDefault();
2. 修改存储过程,统一比较时的排序规则
在存储过程的WHERE子句、JOIN条件等涉及字符串比较的地方,显式用COLLATE子句指定统一的排序规则,比如:
ALTER PROCEDURE [dbo].[sp_SearchPictureInfo] @Prc_ID int, @Cust_ID int, @AppCode nvarchar(50) AS BEGIN SET NOCOUNT ON; -- 在比较时显式指定排序规则,和字段的排序规则保持一致 SELECT * FROM YourPictureTable WHERE Prc_ID = @Prc_ID AND Cust_ID = @Cust_ID AND AppCode = @AppCode COLLATE Cyrillic_General_CI_AS; END
如果是JOIN操作导致的冲突,同样在JOIN条件里加上COLLATE:
FROM TableA a JOIN TableB b ON a.AppCode = b.AppCode COLLATE Cyrillic_General_CI_AS
3. 从根源统一数据库对象的排序规则
如果你的数据库中存在多个排序规则混用的情况,建议检查并统一:
- 查看数据库默认排序规则:
SELECT DATABASEPROPERTYEX('YourDatabaseName', 'Collation') - 查看表字段的排序规则:
SELECT name, collation_name FROM sys.columns WHERE object_id = OBJECT_ID('YourPictureTable')
如果字段的排序规则和数据库默认不一致,可以修改字段的排序规则(注意备份数据,避免数据异常):
ALTER TABLE YourPictureTable ALTER COLUMN AppCode nvarchar(50) COLLATE Cyrillic_General_CI_AS NOT NULL;
这样修改后,后续的参数传递就不会再出现排序规则冲突的问题了。
内容的提问来源于stack exchange,提问作者Stefan Hansch
相关产品推荐
相关产品推荐

