我正在将数据库从SQL Server 2005迁移到2008年。
在测试期间,我发现一个不一致。根据BOL http://msdn.microsoft.com/en-us/library/ms186862(v=SQL.100).aspx(2008)和http://msdn.microsoft.com/en-us/library/ms186862(v=SQL.90).aspx(2005)返回varchar
。到目前为止两者都是一样的。但是,如果我们传递给REPLACE
函数列类型char
,则会出现差异。看看这段代码
declare @test table
(
testcharstring char(25)
)
insert into @test
select 'Hello'
union
select 'World'
union
select 'Hello world '
select
'"'+testcharstring+'"' as original
,'"'+replace(testcharstring,'a','A')+'"' as afterreplace
--,'"'+replace(rtrim(testcharstring),'a','A')+'"'
from @test
SQL Server 2005的结果
original afterreplace
--------------------------- ---------------------------
"Hello " "Hello"
"Hello world " "Hello world"
"World " "World"
SQL Server 2008的结果
original afterreplace
--------------------------- ---------------------------
"Hello " "Hello "
"Hello world " "Hello world "
"World " "World "
SQL Server 2005中的T-SQL甚至删除了合法的尾随空格,而不是说它char(25)
威胁为varchar(25)
。 SQL Server 2008中的T-SQL更仔细地处理类型,并根据它收到的用于转换的类型返回结果
我在不同的T-SQL对象中有数字位置,主要是在触发器中。主要思想是进行最小的更改以在SQL Server 2008中保持相同的行为
可能的方法
REPLACE
功能快速搜索表明我的队友无法研究该选项Rtrim()
个功能与REPLACE
一起使用。这将需要在多个例程(使用char列)中的代码中的确切位置进行替换我想问一下每个人是否有人遇到过这个问题,你是怎么解决的?
也欢迎任何建议,也许我只是不知道服务器实例或数据库级别上的哪些设置可以改变行为。
提前谢谢!
答案 0 :(得分:7)
您有不同的SET ANSI_PADDING选项,也可以由SET ANSI_DEFAULTS
控制目前,REPLACE在两个版本中表现相同。两者(2005,2008)都说:
如果其中一个输入参数是nvarchar数据类型,则返回nvarchar;否则,REPLACE返回varchar。
编辑:有2个连接错误/功能
我上面的回答可能是错误的
检查DB兼容级别:
作为修复,对不起,我会使用rtrim,但这是一个修复?你不能覆盖替换,如果你计划clr紧急,为什么不将replace / rtrim包装在SQL udf中
答案 1 :(得分:1)
根据MS,这是一个正确的行为,SQL2005错了。 在你的代码中你使用Replace()不仅作为核心功能(查找模式并替换为另一种模式)而且还作为Trim()函数(如果没有找到任何至少修剪传入值)强>
但是当你使用Char()时这是错误的。使用Char()作为数据类型的唯一原因是不惜一切代价保留值数据长度。(恕我直言),因为您需要确保返回的值长度总是相同,而不管实际存储的字符数。 当您需要使用字符串连接构建某种结构时,这很重要 与固定长度文件中的输出一样,并且不用担心数据长度检查或转换。 否则你也可以使用varchar()或nvarchar()
http://msdn.microsoft.com/en-us/library/ms143359(v=sql.100).aspx
在SQL Server 2005中,当参数的类型为char时,将修剪在REPLACE函数的第一个输入参数中指定的尾随空格。例如,在语句SELECT'<'中+ REPLACE(CONVERT(char(6),'ABC'),'','L')+'>',值'ABC'被错误地评估为'ABC'。
在SQL Server 2008中,始终保留尾随空格。对于依赖于函数先前行为的应用程序,在为函数指定第一个输入参数时使用RTRIM函数。例如,以下语法将重现SQL Server 2005行为SELECT'<' + REPLACE(RTRIM(CONVERT(char(6),'ABC')),'','L')+'>'。