如何从括号中删除尾随空格,该括号是另一个字符串的子串

时间:2014-07-16 15:29:04

标签: sql-server tsql data-cleansing

我正在使用SQL,而某些列值则表示为{3P Test } * 1 + 0.45%

此处我在测试之后有空格,我想将其更新为{3P Test} * 1 + 0.45%。如何更新该列以删除括号中的尾随空格?

4 个答案:

答案 0 :(得分:1)

如何处理Fiddle Here

SELECT
    l + '{' + rtrim(m) + '}' + r
  FROM
(
SELECT
    substring([Column], 0, a) l,
    substring([Column], a + 1, b - a - 1) m,
    substring([Column], b + 1, len([Column])- b) r
  FROM
(
SELECT
    [Column],
    charindex('{', [Column]) a,
    charindex('}', [Column]) b
  FROM
    [Table]
) [Pos]) [Bits]

正如您将注意到之前的语句选择更正后的数据。你可以这样更新, Fiddle Here

UPDATE [Table]
    SET [Column] = l + '{' + rtrim(m) + '}' + r
  FROM
(
SELECT
    [Column],
    substring([Column], 0, a) l,
    substring([Column], a + 1, b - a - 1) m,
    substring([Column], b + 1, len([Column])- b) r
  FROM
(
SELECT
    [Column],
    charindex('{', [Column]) a,
    charindex('}', [Column]) b
  FROM
    [Table]
) [Pos]) [Bits]
JOIN [Table] ON [Table].[Column] = [Bits].[Column];

如果[Table]的主键已知,则可以改进此声明。

答案 1 :(得分:0)

SELECT LTRIM(RTRIM('{3P Test } * 1 + 0.45%'))

update table set COL1 = LTRIM(RTRIM(COL1))

答案 2 :(得分:0)

您可以在WHILE循环中使用REPLACE函数,例如:

SELECT '{3P Test   } * 1 + 0.45%' AS TestCol INTO #temp 
UNION 
SELECT '{3P Test } * 1 + 0.45%' 

SELECT * FROM #temp

WHILE (SELECT COUNT(*) FROM #temp WHERE TestCol LIKE '% }%') > 0
  BEGIN
    UPDATE #temp
    SET TestCol = REPLACE(TestCol, ' }', '}')
  END

SELECT * FROM #temp 

DROP TABLE #temp 

答案 3 :(得分:0)

如果这是一次性更新,或者如果没有那么多行,那么迭代方法(如问题评论中所建议的)可以工作,但这是不是如果有很多数据你想要做的事情,因为UPDATE的每次迭代都是一个事务(除非你在BEGIN TRANSACTION循环之前显式执行WHILE,但是如果那个操作需要一段时间它会阻止表格进行其他操作。)

例如:

DECLARE @TestTable TABLE (String NVARCHAR(4000));
INSERT INTO @TestTable (String) VALUES (N'{3P Test   } * 1 + 0.45%');

SELECT * FROM @TestTable;

WHILE (EXISTS(
          SELECT *
          FROM @TestTable tmp
          WHERE tmp.String LIKE N'% }%'
          )
      )
BEGIN
   UPDATE TOP (100) tmp -- do this in batches to reduce transaction size
   SET tmp.String = REPLACE(tmp.String, N' }', N'}')
   FROM @TestTable tmp
   WHERE tmp.String LIKE N'% }%';
END;

SELECT * FROM @TestTable;

OR ,这是@Jodrell提​​出的CHARINDEX想法的简化版本,它使用CTE而不是多个子查询(不需要JOIN到基数table)并将字符串分成2个而不是3个:

DECLARE @TestTable TABLE (String NVARCHAR(4000));
INSERT INTO @TestTable (String) VALUES (N'{3P Test               } * 1 + 0.45%');
INSERT INTO @TestTable (String) VALUES (N'{3P Test     4       } * 1 + 0.45%');

SELECT * FROM @TestTable;

WHILE (EXISTS(
          SELECT *
          FROM @TestTable tmp
          WHERE tmp.String LIKE N'% }%'
          )
      )
BEGIN

   ;WITH cte AS
   (
      SELECT TOP (100)
             tmp.String,
             CHARINDEX(N'}', tmp.String) AS [RightBracketLocation]
      FROM @TestTable tmp
      WHERE tmp.String LIKE N'% }%'
   )
   UPDATE cte
   SET cte.String =
             RTRIM(SUBSTRING(cte.String, 1, (cte.[RightBracketLocation] - 1)))
             + SUBSTRING(cte.String, [RightBracketLocation], 4000)
   FROM cte;

END;

SELECT * FROM @TestTable;

但是,如果这是一个常见的操作,那么更直接和更直接的东西会更好,例如正则表达式。没有内置的正则表达式函数,因此您需要使用SQLCLR来获取该功能。例如:

DECLARE @Test NVARCHAR(4000);
SET @Test = N'{3P Test   } * 1 + 0.45%';

SELECT SQL#.RegEx_Replace(@Test, N'\s+}', N'}', -1, 1, N'IgnoreCase');

在示例中,我使用的是SQL#库(我是其作者,但正则表达式函数在免费版中可用)。