请找到我写的这个SQL函数
CREATE FUNCTION [dbo].[TL_ReplaceOldBrand]
(
@string NVARCHAR(max),
@BrandName NVARCHAR(50) = N'Brand',
@BrandNameNew NVARCHAR(50) = N'NewBrand'
)
RETURNS NVARCHAR(max)
AS
BEGIN
DECLARE @ResultString NVARCHAR(max) = @string
DECLARE @PossibleCharactersBegin NVARCHAR(100) = N'%[ ,.;:/?!-‘’''"(<>)' + Char(13) + Char(10) + ']'
DECLARE @PossibleCharactersEnd NVARCHAR(100) = N'[ ,.;:/?!-‘’''"(<>)' + Char(13) + Char(10) + ']%'
DECLARE @searchString NVARCHAR(100)
--The brand name ONLY
IF @ResultString = @BrandName
SET @ResultString = REPLACE(@ResultString, @BrandName, @BrandNameNew)
--The brand name at BEGINNING
SET @searchString = N'' + @BrandName + @PossibleCharactersEnd
WHILE PATINDEX(@searchString, @ResultString) > 0
SET @ResultString = STUFF(@ResultString, PATINDEX(@searchString, @ResultString), LEN(@BrandName), @BrandNameNew)
--The brand name BETWEEN words
SET @searchString = N'' + @PossibleCharactersBegin + @BrandName + @PossibleCharactersEnd
WHILE PATINDEX(@searchString, @ResultString) > 0
SET @ResultString = STUFF(@ResultString, PATINDEX(@searchString, @ResultString) + 1, LEN(@BrandName), @BrandNameNew)
--The brand name at the END
SET @searchString = N'' + @PossibleCharactersBegin + @BrandName
WHILE PATINDEX(@searchString, @ResultString) > 0
SET @ResultString = STUFF(@ResultString, PATINDEX(@searchString, @ResultString) + 1, LEN(@BrandName), @BrandNameNew)
RETURN @ResultString
END
当我像这样使用它时,就像这样:
select dbo.TL_ReplaceOldBrand(N'I want to replace, Brand by NewBrand, in a long long text which have multiple Brand occurences.', DEFAULT, DEFAULT)
没有发生替换。但是如果我在函数定义中用VARCHAR替换所有NVARCHAR,它就可以正常工作并按照我想要的那样用 NewBrand 替换 Brand 。
任何人都可以向我解释原因?
要回答这个问题,为什么我要使用NVARCHAR而不是VARCHAR,这是因为该函数用于包含多个语言文本的列,如中文,泰文或韩文等特殊字符
答案 0 :(得分:0)
最后,我找到了另一个解决问题的方法
请找到我写的新功能
CREATE FUNCTION [dbo].[TL_ReplaceOldBrand]
(
@string NVARCHAR(max),
@BrandName VARCHAR(50) = N'Brand',
@BrandNameNew VARCHAR(50) = N'NewBrand'
)
RETURNS NVARCHAR(max)
AS
BEGIN
DECLARE @ResultString VARCHAR(max) = @string
DECLARE @NResultString NVARCHAR(max) = @string
--REMARK: CHAR(13): Carriage Return
-- : CHAR(10): Line Feed
-- : CHAR(9) : Tabulation
DECLARE @PossibleCharactersBegin VARCHAR(100) = N'%[ ,.;:/?!-‘’''"(<>)' + Char(13) + Char(10) + Char(9) + ']'
DECLARE @PossibleCharactersEnd VARCHAR(100) = N'[ ,.;:/?!-‘’''"(<>)' + Char(13) + Char(10) + Char(9) + ']%'
DECLARE @searchString VARCHAR(100)
DECLARE @index int = 0
--The brand name ONLY
IF @NResultString = @BrandName
BEGIN
SET @NResultString = REPLACE(@NResultString, @BrandName, @BrandNameNew)
SET @ResultString = CONVERT(VARCHAR(MAX), @NResultString)
END
--The brand name at BEGINNING
SET @searchString = N'' + @BrandName + @PossibleCharactersEnd
SET @index = PATINDEX(@searchString, @ResultString)
WHILE @index > 0
BEGIN
SET @NResultString = STUFF(@NResultString, @index, LEN(@BrandName), @BrandNameNew)
SET @ResultString = @NResultString
SET @index = PATINDEX(@searchString, @ResultString)
END
--The brand name BETWEEN words
SET @searchString = N'' + @PossibleCharactersBegin + @BrandName + @PossibleCharactersEnd
SET @index = PATINDEX(@searchString, @ResultString)
WHILE @index > 0
BEGIN
SET @NResultString = STUFF(@NResultString, @index + 1, LEN(@BrandName), @BrandNameNew)
SET @ResultString = @NResultString
SET @index = PATINDEX(@searchString, @ResultString)
END
--The brand name at the END
SET @searchString = N'' + @PossibleCharactersBegin + @BrandName
SET @index = PATINDEX(@searchString, @ResultString)
WHILE @index > 0
BEGIN
SET @NResultString = STUFF(@NResultString, @index + 1, LEN(@BrandName), @BrandNameNew)
SET @ResultString = @NResultString
SET @index = PATINDEX(@searchString, @ResultString)
END
RETURN @NResultString
END
我使用了替换变量来保持输入字符串的NVARCHAR格式,并在其VARCHAR等效项上使用patindex,它的工作正常。