更新字符串中的多个子字符串

Update multiple substrings within a string

我在 SQL table 中存储了一个文本字符串,其中包含以下所有文本。格式是 XML 但字段定义是 varchar.

我正在使用 SQL Server 2012 来查询此数据:

<?xml version="1.0" encoding="utf-16"?>  
    <SaveFileContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    
            <Mappings>  
                  <SaveFileModel Header="Model1" FullPath="Model1" ViewType="ModelView" /> 
   
                  <SaveFileModel Header="xyz" FullPath="\server\directory\" ViewType="TradeView" />      

                  <SaveFileModel Header="Model2" FullPath="Model2" ViewType="ModelView" />

                  <SaveFileModel Header="Model3" FullPath="Model3" ViewType="ModelView" /> 

                  <SaveFileModel Header="abc" FullPath="\server\directory\" ViewType="TradeView" />    

                  <SaveFileModel Header="def" FullPath="\server\directory\" ViewType="TradeView" />

                  <SaveFileModel Header="ghi" FullPath="\server\directory\" ViewType="TradeView"/>
            </Mappings>  
    </SaveFileContext>

如何更新或删除 viewtype="ModelView" 的整行文本?

我想删除这个字符串中 viewtype="ModelView" 的任何行,并将其替换为空白 space。在上面的示例中,我想总共删除 3 行并保留其余行。

最后我希望字符串如下所示(请记住所有行都包含在 1 个字符串中。我只是将它们分开以便于查看。

<?xml version="1.0" encoding="utf-16"?>  
    <SaveFileContext xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">    
            <Mappings>  
                  <SaveFileModel Header="xyz" FullPath="\server\directory\" ViewType="TradeView" />      

                  <SaveFileModel Header="abc" FullPath="\server\directory\" ViewType="TradeView" />    

                  <SaveFileModel Header="def" FullPath="\server\directory\" ViewType="TradeView" />

                  <SaveFileModel Header="ghi" FullPath="\server\directory\" ViewType="TradeView"/>
            </Mappings>  
    </SaveFileContext>

这是我当前用来替换行的查询,但要替换的值非常具体。我基本上是在输入要替换的字符串。

IF OBJECT_ID('tempdb..#replacement') IS NOT NULL
   DROP TABLE #replacement

CREATE TABLE #replacement (
   string_pattern VARCHAR(100),
   string_replacement VARCHAR(5)
);

INSERT INTO #replacement (
   string_pattern,
   string_replacement
)
VALUES
   ('<SaveFileModel Header="Model1" FullPath="Model1" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model2" FullPath="Model2" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model3" FullPath="Model3" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model4" FullPath="Model4" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model5" FullPath="Model5" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model6" FullPath="Model6" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model7" FullPath="Model7" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model8" FullPath="Model8" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model9" FullPath="Model9" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model10" FullPath="Model10" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model11" FullPath="Model11" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model12" FullPath="Model12" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model13" FullPath="Model13" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model14" FullPath="Model14" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model15" FullPath="Model15" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model16" FullPath="Model16" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model17" FullPath="Model17" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model18" FullPath="Model18" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model19" FullPath="Model19" ViewType="ModelView" />', ''),
   ('<SaveFileModel Header="Model20" FullPath="Model20" ViewType="ModelView" />', '');

DECLARE @string AS VARCHAR(MAX),
        @userident varchar(20);

DECLARE userviewdef CURSOR FOR
SELECT
        UserID
    FROM
        TableSettings where section = 'user view session'

OPEN userviewdef;

FETCH NEXT FROM userviewdef INTO
    @userident;

WHILE @@FETCH_STATUS = 0
    BEGIN
        select @string = varcharvalue from tablesettings where section = 'user view session' and userid = @userident

        -- Perform all replacements
        SELECT @string = REPLACE(@string, string_pattern, string_replacement) FROM #replacement;

        -- Return new string
        --PRINT @string;
        
        update tablesettings
        set varcharvalue = @string
        where section = 'user view session' and userid = @userident
        

        FETCH NEXT FROM userviewdef INTO
        @userident;

    END;

CLOSE userviewdef;

DEALLOCATE userviewdef;

在某些情况下,字符串可能如下所示,但不会被删除,因为它不适合我编码为要删除的任何字符串。我想找到一种简单的方法来删除 ViewType="ModelView" 的任何行,因为这是我的标准。

<SaveFileModel Header="ThisIsSomethingElse" FullPath="Model1" ViewType="ModelView" /> 

21 年 4 月 21 日: 在按照@FrankPl 的建议使用 XML 之后,这就是我想出的。结果returns 一片空白space。我可能对 XML 查询部分的编码不正确,需要一些帮助:

DECLARE @stringXML XML,
        @finalString varchar(max),
        @userident varchar(20);

        

DECLARE userviewdef CURSOR FOR

SELECT
        UserID
    FROM
        TableSettings where section = 'user view session';

OPEN userviewdef;

FETCH NEXT FROM userviewdef INTO
    @userident;

WHILE @@FETCH_STATUS = 0
    BEGIN

        select @stringXML = varcharvalue from tablesettings where section = 'user view session' and userid = @userident

        
        select @stringXML.query('
            for $item in (/SaveFileContext/Mappings/SaveFileModel)
            return if ($item[@ViewType = "ModelView"]) then string($item) else ""
            ')

        select @finalString = convert(varchar(max), @stringXML)

        -- Return new string
        PRINT @finalstring;
        

        FETCH NEXT FROM userviewdef INTO
        @userident;

    END;

CLOSE userviewdef;

DEALLOCATE userviewdef;

如果您将 @step 变量声明为数据类型 XML 而不是 varchar,您可以使用 XQuery 来处理数据,在本例中 a FLOWR expression in curly文字 XML 元素内的大括号,大括号从文字模式切换到 XPath 模式:

SELECT @string.query('
    <SaveFileContext>    
        <Mappings> {
   for $item in (/SaveFileContext/Mappings/SaveFileModel)  
   return if ($item[@ViewType = "ModelView"]) then $item else ()
      } </Mappings>  
   </SaveFileContext>
'

XML 声明和名称空间被 SQL 服务器 XML 处理器吞没。

此解决方案假设数据是有效的 XML 片段。

请注意 - 由于整个查询需要是一个 SQL 字符串(即在单引号中),并且 XQuery 接受双引号和单引号中的字符串,为简单起见,我使用了双引号这里。或者,我可以在 SQL 字符串中使用双引号将它们转义。