【问题标题】:Temp procedure messes up collation临时程序弄乱了排序规则
【发布时间】:2018-05-22 13:51:12
【问题描述】:

问题: 我有一个由 .NET 应用程序创建的程序(简化):

create procedure #SaveData
@InValue varchar(128)
as
begin
    insert into Production.TargetTable (PREFIX_Value) select @InValue
end

问题是,数据库使用 SQL_SLOVAK_CP1250_CI_AS 排序规则。 TempDB 使用默认的 SQL_Latin1_General_CP1_CI_AS 排序规则。

问题简化:

-- this doesnt work, returns RTC
create procedure #SaveData
@InValue varchar(128)
as
begin
    select @InValue
end

-- this doesnt work, returns RTC
create procedure #SaveData
@InValue varchar(128)
as
begin
    select @InValue collate SQL_SLOVAK_CP1250_CI_AS
end

-- this does work, returns ŘŤČ
create procedure SaveData
@InValue varchar(128)
as
begin
    select @InValue
end

这会导致保存 RTC 而不是测试字符串 ŘŤČ。 当我从过程名称中删除 # 并且不将其创建为临时过程时,一切正常。

现在,一种可行的解决方法是将参数类型从 varchar 更改为 nvarchar。但这将是很多工作(许多不同的程序)。有没有可行的全局方法?

谢谢你,祝你有美好的一天

【问题讨论】:

  • 也许您应该将服务器的排序规则更改为 SQL_SLOVAK_CP1250_CI_AS?
  • @DenisRubashkin 会尝试,但似乎是一个核武器选项。可能是同时在服务器上运行的具有不同排序规则的其他数据库。

标签: sql-server stored-procedures procedure collation tempdb


【解决方案1】:

问题在于列排序规则。传递给它的任何值都将其排序规则更改为列排序规则:

declare @table table(txt varchar(10) collate SQL_Latin1_General_CP1_CI_AS)
insert into @table values ('ŘŤČ' collate SQL_SLOVAK_CP1250_CI_AS)
--result will be changed, even with explicit collation
select * from @table
go

declare @table table(txt varchar(10) collate SQL_SLOVAK_CP1250_CI_AS)
insert into @table values ('ŘŤČ')
--correct output
select * from @table
go

所以你必须改变列中的排序规则:

alter table TABLE_NAME alter column TextCol varchar(...) collate SQL_SLOVAK_CP1250_CI_AS 

【讨论】:

  • 谢谢,但不,会说排序规则来得太晚了,在参数传递给过程后,它会被“截断”为 Latin1 排序规则
  • 是的,但是临时过程存储到一个普通的非临时表中,并且排序规则正常。
  • 临时对象保存在具有拉丁排序规则的主数据库中。如果没有#,您将在您的一个数据库中创建此过程,该数据库(很可能)具有斯洛伐克语排序规则。因此差异。
  • 我明白,问题是,我如何才能真正将 tempdb(主要是临时过程)与具有不同排序规则的不同数据库一起使用。
  • 那么,在程序中,你必须明确整理。
猜你喜欢
  • 2015-03-14
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-09
相关资源
最近更新 更多