用于删除多余字符的SQL脚本

时间:2016-03-24 12:05:57

标签: sql sql-server regex

我的MSSQL 2012数据库在某个包含文本的A列中存在一些数据问题。

</B>标记之后出现了许多不必要的不​​必要字符,例如:

'<B>Something</B>g' where should stand '<B>Something</B>'
'<B>SomethingElse</B>e' where should stand '<B>SomethingElse</B>'

以前的值是较大文本的一部分,例如,可以多次出现 - &gt;专栏示例:

'Some text is here <B>Something</B>g and also here <B>SomethingElse</B>e more text'

这些“额外”字符始终与<B></B>标记之间的最后一个字符相同。 我想创建SQL脚本:

  1. </B>代码

  2. 之后删除多余的字符
  3. 仅当额外字符与之间的最后一个字符相同时 <B></B>标签(作为附加检查)。编辑:这不是绝对必要的

  4. 我假设有一种调用替换函数的方法,就像在这个伪代码中,其中X代表任何字符。

    replace(X</B>X, X</B>);
    

    但我在SQL方面不是很好,也不知道如何实现2.检查。

    感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

如果您的列中没有其他字符,那么只有这些字符串,您可以在列update上使用此a语句:

update  mytable
set     a = left(a, len(a)-1)
where   left(right(a, 6), 5) = right(a, 1) + '</B>'

以下是fiddle中的一些测试用例。

要在较长的字符串中替换此类事件(可能存在多个字符串),则可以使用此recursive query

WITH recursive AS (
    SELECT replace(a, '</B>', 'µ') as a
    FROM   mytable
    UNION ALL
    SELECT stuff(a, charindex('µ', a),
           CASE WHEN substring(a, charindex('µ', a)-1, 1)
                   = substring(a, charindex('µ', a)+1, 1)
                THEN 2 
                ELSE 1 
           END, '</B>')
    FROM   recursive
    WHERE  charindex('µ', a) > 0
)
SELECT * 
FROM   recursive
WHERE  charindex('µ', a) = 0

出现在多个地方的角色µ应该是您不希望在数据中出现过的角色。如有必要,请用其他字符替换它。

这是fiddle

上面的查询变成了一个更新语句,如下所示。它假定您的表具有主键 id

WITH recursive AS (
    SELECT id, 
           replace(a, '</B>', 'µ') as a,
           0 as modified
    FROM   mytable
    UNION ALL
    SELECT id, 
           stuff(a, charindex('µ', a),
           CASE WHEN substring(a, charindex('µ', a)-1, 1)
                   = substring(a, charindex('µ', a)+1, 1)
              THEN 2 ELSE 1 END, '</B>'),
           1
    FROM   recursive
    WHERE  charindex('µ', a) > 0
)
UPDATE     mytable
SET        a = recursive.a
FROM       recursive
INNER JOIN mytable 
        ON mytable.id = recursive.id 
WHERE      charindex('µ', recursive.a) = 0 
AND        recursive.modified = 1;

这也是fiddle

答案 1 :(得分:1)

您可以创建标量函数:

CREATE FUNCTION [dbo].[RemoveChars] 
(
    -- Add the parameters for the function here
    @InputStr NVARCHAR(50)
)
RETURNS NVARCHAR(50)
AS
BEGIN
    DECLARE @SearchStr NVARCHAR(4) = '</B>'
    DECLARE @LastChar CHAR(1)
    DECLARE @LastCharInStr CHAR(1)
    DECLARE @Result NVARCHAR(50)

    SET @LastChar = SUBSTRING(@InputStr, 
                    CHARINDEX(@SearchStr, @InputStr) + LEN(@SearchStr), 1)
    SET @LastCharInStr = SUBSTRING(@InputStr, 
                         CHARINDEX(@SearchStr, @InputStr) - 1, 1)

    IF (@LastCharInStr = @LastChar) 
            SET @Result = SUBSTRING(@InputStr, 0, 
            CHARINDEX(@SearchStr, @InputStr) + LEN(@SearchStr))
    ELSE
        SET @Result = @InputStr

    RETURN @Result
END

然后叫它:

UPDATE MyTable
Set A = dbo.RemoveChars(A)

就个人而言,我会创建第二个函数,仅将更新应用于字符串中最后一个字符与字母后面的字符之间存在差异的值,但是由您自行决定。