繁体   English   中英

根据来自 XML 类型列的匹配项更新 XML 节点值

[英]Update XML node value based on a match from XML type column

我有一个带有 XML 列的 SQL 表。

表结构是

CREATE TABLE [dbo].[UserSettings](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NOT NULL,    
    [UserName] [varchar](100) NULL, 
    [Setting] [xml] NULL,   
    [CreateDate] [datetime] NOT NULL
)

设置 xml 列如下所示:

<UserSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <UserID>1</UserID>
  <Reports>
        <string>Report - 1</string>
        <string>Report - 2</string>
        <string>Report - 3</string>
        <string>Report - 4</string>
  </Reports>
</UserSettings>

我想将<Reports> Report - 1 更新为 Report - One,将 Report - 2 更新为 Report - Two

而且,如果有一个值 Report - 4 那么我想从<Reports>删除它

所以我在专栏中的最终结果应该是这样的:

<UserSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <UserID>1</UserID>
  <Reports>
        <string>Report - One</string>
        <string>Report - Two</string>
        <string>Report - Three</string>     
  </Reports>
</UserSettings>

编辑:我尝试过 REPLACE 方法。 我不确定这是否是最有效的方法。

update UserSettings
set Setting=REPLACE(convert(varchar(max),Setting),'<string>Report - 1</string>','<string>Report - One</string>')
where convert(varchar(max),Setting) like '%<string>Report - 1</string>%'

编辑:我阅读了modify() 方法,但报告的顺序可以是任何顺序。 我无法让我的查询使用它。

简单的方法是使用 Replace as string,但是如果您不想在任何地方替换该值(例如在<Reports>标记之外),则此方法没有用

-- to update report 1 to 3 ( I just did it for 1):
update UserSettings
set Setting = replace(cast(Setting as nvarchar(max)) , '<string>Report - 1</string>','<string>Report - one</string>')

-- to remove report 4 
update UserSettings
set Setting = replace(cast(Setting as nvarchar(max)) , '<string>Report - 4</string>','')

您可以尝试不同的方法。

代替查找和替换,即修改,可以通过 XQuery 及其 FLWOR 表达式动态组合 XML。

SQL

-- DDL and sample data population, start
DECLARE @UserSettings TABLE (
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [int] NOT NULL,    
    [UserName] [varchar](100) NULL, 
    [Setting] [xml] NULL,   
    [CreateDate] [datetime] NOT NULL
);
INSERT INTO @UserSettings (UserID, UserName, Setting, CreateDate)
VALUES
(0, 'John', N'<UserSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <UserID>1</UserID>
    <Reports>
        <string>Report - 1</string>
        <string>Report - 2</string>
        <string>Report - 3</string>
        <string>Report - 4</string>
    </Reports>
</UserSettings>', 
    GETDATE()
);
-- DDL and sample data population, end

UPDATE @UserSettings
SET Setting = Setting.query('<UserSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xmlns:xsd="http://www.w3.org/2001/XMLSchema">
{
    for $x in /UserSettings/*[local-name()!="Reports"]
    return $x,
        element Reports {
            for $y in ("One","Two","Three")
            return <string>{concat("Report - ", $y)}</string>
        }
}
</UserSettings>');

-- test
SELECT * FROM @UserSettings;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM