我有一个持久的计算列,调用Scalar Valued Function
。如您所知,此函数需要具有确定性才能保持该值。即使REPLACE函数以确定的方式运行(我不能认为它不是这样的情况),SQL Server似乎将其解释为不确定的。因此,我不能在函数中使用它。
我尝试将一些非英语字符转换为英语。区分大小写在这里很重要。我想分别将ğĞüÜşŞıİöÖçÇ
的字母转换为gGuUsSiIoOcC
。我可以通过使用类似的东西来实现它(以#34;非确定性方式)#。
SET @ColumnValue = REPLACE(@ColumnValue COLLATE SQL_Latin1_General_CP1253_CS_AS, 'ı', 'i') --This character("ı") is converted to "?" after collation so that I manually replace it
SET @ColumnValue = @ColumnValue COLLATE SQL_Latin1_General_CP1253_CS_AS --This line takes care of the other characters
由于REPLACE
和COLLATE
,SQL Server将上面的代码解释为非确定性(demo)(我认为它虽然是确定性的......)。
我尝试的另一件事是在WHILE
循环中使用CHARINDEX和STUFF,但由于需要区分大小写,因此需要使用归类。如果没有排序规则,SQL Server会将其视为确定性的。
我有什么选择?
答案 0 :(得分:5)
您的列真的是varchar
类型,而不是nvarchar
吗?
看起来COLLATE SQL_Latin1_General_CP1253_CS_AS
对nvarchar
具有确定性,但对varchar
具有不确定性。
以下功能是确定性的。
请注意,您需要在字符串文字前加N
作为前缀才能正常工作。
CREATE FUNCTION dbo.TestFunc1 (@ColumnValue NVARCHAR(4000))
RETURNS NVARCHAR(4000)
WITH SCHEMABINDING
AS
BEGIN
SET @ColumnValue = REPLACE(@ColumnValue COLLATE SQL_Latin1_General_CP1253_CS_AS, N'ı', N'i') --This character("ı") is converted to "?" after collation so that I manually replace it
SET @ColumnValue = @ColumnValue COLLATE SQL_Latin1_General_CP1253_CS_AS --This line takes care of the other characters
RETURN @ColumnValue
END
如果您需要使用varchar
,那么我将使用二进制排序规则来替换特定字符。以下功能也是确定性的。
CREATE FUNCTION dbo.TestFunc2 (@ColumnValue VARCHAR(8000))
RETURNS VARCHAR(8000)
WITH SCHEMABINDING
AS
BEGIN
SET @ColumnValue = REPLACE(@ColumnValue COLLATE Latin1_General_BIN2, N'ı', N'i')
SET @ColumnValue = REPLACE(@ColumnValue COLLATE Latin1_General_BIN2, N'ö', N'o')
...
RETURN @ColumnValue
END