使用 T-SQL 在字母数字字符串中的字母字符周围添加引号?

Add quotes around alpha characters in alphanumeric strings using T-SQL?

我想在字母数字字符串中的字母周围添加引号。例如:如果我的字符串是 8AB8973,则预期输出是 8'AB'8973。没有出现数字和字符的特定模式。我尝试 运行 我在 Whosebug 上找到的以下代码,但它在数字和字母之间添加了 space,当我尝试用引号替换 space 时,查询永远需要至 运行.

    DECLARE @position INT;
    DECLARE @string VARCHAR(max);

    SET @string = '9FX8173'

    WHILE 1 = 1
      BEGIN
          SET @position = (SELECT Min(position)
                           FROM   (VALUES (Patindex('%[^ 0-9][0-9]%', @string)),
                                          (Patindex('%[0-9][^ 0-9]%', @string))) AS T(position)
                           WHERE  T.position > 0);

          IF @position IS NULL
            BREAK;

          SET @string = Stuff(@string, @position + 1, 0, ' ');
       END

       PRINT @string

除了在 STUFF 函数中用引号替换 space 之外,您还需要在 PATINDEX 搜索表达式中执行相同的操作:

DECLARE @position INT;
DECLARE @string VARCHAR(max);

SET @string = '9FX8173';

WHILE 1 = 1
BEGIN
    SET @position = (
        SELECT MIN(position)
        FROM (VALUES (PATINDEX('%[^''0-9][0-9]%', @string)),
                     (PATINDEX('%[0-9][^''0-9]%', @string))) AS T(position)
        WHERE  T.position > 0);

    IF @position IS NULL
        BREAK;

    SET @string = STUFF(@string, @position + 1, 0, '''');
END

PRINT @string;

对于纯粹基于集合的高性能解决方案,您可以使用 PatternSplitCM

函数

-- PatternSplitCM will split a string based on a pattern of the form 
-- supported by LIKE and PATINDEX 
-- 
-- Created by: Chris Morris 12-Oct-2012 
CREATE FUNCTION dbo.PatternSplitCM
(
  @List               VARCHAR(8000) = NULL,
  @Pattern            VARCHAR(50)
) RETURNS TABLE WITH SCHEMABINDING 
AS 
RETURN
    WITH numbers AS (
      SELECT TOP(ISNULL(DATALENGTH(@List), 0))
       n = ROW_NUMBER() OVER(ORDER BY (SELECT NULL))
      FROM
      (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d (n),
      (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) e (n),
      (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) f (n),
      (VALUES (0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) g (n))

    SELECT
      ItemNumber = ROW_NUMBER() OVER(ORDER BY MIN(n)),
      Item = SUBSTRING(@List,MIN(n),1+MAX(n)-MIN(n)),
      [Matched]
     FROM (
      SELECT n, y.[Matched], Grouper = n - ROW_NUMBER() OVER(ORDER BY y.[Matched],n)
      FROM numbers
      CROSS APPLY (
          SELECT [Matched] = CASE WHEN SUBSTRING(@List,n,1) LIKE @Pattern THEN 1 ELSE 0 END
      ) y
     ) d
     GROUP BY [Matched], Grouper
GO

解决方案

DECLARE @string VARCHAR(max);

SET @string = '9FX81D73';

select newstring = 
(
  select case [matched] when 1 then  ''''+item+'''' else item end
  from dbo.PatternSplitCM(@string, '[a-zA-Z]')
  order by itemnumber
  for xml path('')
);

结果

newstring
----------------------
9'FX'81'D'73