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

时间:2017-11-03 21:37:23

标签: sql-server tsql split quotes alphanumeric

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

    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

2 个答案:

答案 0 :(得分:0)

除了用STUFF函数中的引号替换空格外,还需要在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;

答案 1 :(得分:0)

对于纯粹基于集合的高性能解决方案,您可以使用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