我有一个持久计算列,它调用标量值函数
。如您所知,该函数需要具有确定性才能保留该值。即使REPLACE函数以确定性方式运行(我想不出有什么情况不是),SQL Server 似乎将其解释为不确定性。因此,我不能在函数中使用它。
我尝试做的是将一些非英语字符转换为英语。区分大小写在这里很重要。我想将 ğĞüÜşŞııöÖçÇ
的字母分别转换为 gGuUsSiIoOcC
。我可以通过使用类似的东西来实现它(以“非确定性”方式):
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 )(但我认为它是确定性的..)。
我尝试的另一件事是使用 CHARINDEX与 STUFF在 WHILE
循环中,但由于需要区分大小写而需要使用排序规则。如果没有排序规则,SQL Server 会将其视为确定性的。
我有什么选择?
最佳答案
您的列确实是 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
关于sql - 确定性字符串替换和整理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44674733/