有人可以帮助我更新 sql server 2019 代码以与 sql server 2008 r2 一起使用吗?

Could someone assist me updating a sql server 2019 code to work with sql server 2008 r2?

我有这段代码 运行 在 sql 服务器 2019 上非常完美,但我认为很多功能只在 2017+ 版本中引入。我正在使用 sql 服务器 2008r2,想知道是否有人可以帮助我将其重新编码为 运行。谢谢。

        declare 
            @s1 varchar(100)='The Elf on the Shelf: A Christmas Musical. (Touring)',
            @s2 varchar(100)='The Elf on the Shelf Musical, Baltimore';
        
        with words as (
          select 1 s, Replace(Translate(value,'!"*():;,.','|||||||||'),'|','') word
          from String_Split(@s1,' ')
          union all
          select 2, Replace(Translate(value,'!"*():;,.','|||||||||'),'|','')
        from String_Split(@s2,' ')
        ), matching as (
            select *, Row_Number() over(partition by word order by s) rn
            from words
        ), final as (
            select * , Count(*) over(partition by word, s) repeating, Count(*) over() * 1.0 totwords, sum(Iif(s=1,1,0)) over() s1words
            from matching
            outer apply(values(Iif(rn=2 and rn=s,1,0)))x(p)
        )
        select (Sum (p) + max(case when s=1 and repeating>1 then repeating end))
            / Max(Iif(totwords/s1words>0.5, totwords-s1words, s1words)) * 100 [Matching Words %]
        from final

要在 SQL Server 2008 R2 中完成相同的工作,效率会大大降低,您将需要创建一些帮助用户定义的函数。

第一个是用于拆分字符串的通用方法,用于替换 STRING_SPLIT()。实际上有数百种不同的分隔符,但请注意,有些可能无法正确处理 space 作为分隔符。这只是我从 my own stash of resources on splitting strings:

抓取的第一个
CREATE FUNCTION dbo.SplitStrings
(
   @List       nvarchar(max),
   @Delimiter  nvarchar(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
   RETURN 
   (  
      SELECT Item = y.i.value(N'(./text())[1]', N'nvarchar(4000)')
      FROM 
      ( 
        SELECT x = CONVERT(XML, N'<i>' 
          + REPLACE(@List, @Delimiter, N'</i><i>') 
          + N'</i>').query(N'.')
      ) AS a CROSS APPLY x.nodes('i') AS y(i)
   );

接下来我们需要一个函数来迭代一个字符串,一次一个字符,并删除坏字符(这将替换您现有代码中的 TRANSLATE())。一些解决方案将使用 while 循环和 patindex,这没关系,但其他解决方案只会说嵌套 17 REPLACE() 调用,这使得代码无法阅读和维护。这是我想出的:

CREATE FUNCTION dbo.CreateCleanString 
(
  @String        nvarchar(4000),
  @IgnorePattern nvarchar(255) 
)
RETURNS @Set TABLE
(
  listpos   int,
  character nchar(1)
)
WITH SCHEMABINDING
AS
BEGIN
  DECLARE @pos int, @ThisCharacter nchar(1);
  SET @pos = 1

  WHILE @pos <= LEN(@String)
  BEGIN
    SET @ThisCharacter = SUBSTRING(@String, @pos, 1);
    IF @IgnorePattern NOT LIKE N'%' + @ThisCharacter + N'%'
    BEGIN
      INSERT @Set(listpos, character)
        SELECT COALESCE(MAX(listpos) + 1, 1), SUBSTRING(@String, @pos, 1)
        FROM @Set;
    END
    SET @pos = @pos + 1;
  END
  RETURN;
END
GO

有了这两个,您现在可以编写这个复杂得多的查询来获得结果。我不打算列举所有差异,但它们从第一行开始(SQL Server 2008 不支持内联 declare/set),然后继续 IIF()参考重写为 CASE expressions.

DECLARE @pattern nvarchar(255), @s1 nvarchar(4000), @s2 nvarchar(4000);
          
SELECT @pattern = N'!"*():;,.',
       @s1 = N'The Elf on the Shelf: A Christmas Musical. (Touring)',
       @s2 = N'The Elf on the Shelf Musical, Baltimore';

;WITH clean_src AS -- break it apart by character and get rid of bad ones
(
  SELECT src.s, src.str, c.listpos, c.character 
    FROM (VALUES(1,@s1),(2,@s2)) AS src(s,str) 
    CROSS APPLY dbo.CreateCleanString(src.str, @pattern) AS c),
clean_output AS -- put it back together
(
  SELECT s, rn = ROW_NUMBER() OVER (PARTITION BY s ORDER BY c.listpos), 
    CleanString = (SELECT clean_src.character 
      FROM clean_src WHERE s = c.s ORDER BY c.listpos 
      FOR XML PATH(''), TYPE).value(N'./text()[1]', N'nvarchar(4000)') 
    FROM clean_src AS c),
words AS -- now break it apart again, this time into words
(
  SELECT s, word = Item, rn = ROW_NUMBER() OVER (PARTITION BY Item ORDER BY s) 
    FROM clean_output CROSS APPLY dbo.SplitStrings(CleanString, ' ')
    WHERE rn = 1),
final AS -- do some matching and generate aggregates
(
  SELECT s, word, rn, x.p,
    repeating = COUNT(*) OVER (PARTITION BY word, s),
    totwords  = COUNT(*) OVER() * 1.0, 
    s1words   = SUM(CASE WHEN s = 1 THEN 1 ELSE 0 END) OVER()
  FROM words 
  OUTER APPLY (VALUES(CASE WHEN rn = 2 and rn = s THEN 1 ELSE 0 END)) AS x(p)
)
SELECT [Matching Words %] = (SUM(p) 
  + MAX(CASE WHEN s = 1 AND repeating > 1  THEN repeating END))
  / MAX(CASE WHEN totwords / s1words > 0.5 THEN totwords - s1words 
  ELSE s1words END) * 100 
FROM final;
  • SQL Server 2019 上的原始版本:db<>fiddle
  • 此方法,支持的最旧版本 (2014):db<>fiddle

现在,我没有 SQL Server 2008 R2 实例来对此进行测试,事实上,我四处询问,但我不知道还有谁这样做。真的是时候考虑最终升级了,恕我直言。