【问题标题】:Update SQL Server XML data with namespace使用命名空间更新 SQL Server XML 数据
【发布时间】:2020-09-11 15:29:48
【问题描述】:

我有一个临时表,可以在其中组合各种值。组装完这些值后,我想查询表以生成一个 XML 元素,该元素将被插入以更新表列中更大的 XML 数据。这是我正在使用的 TSQL。

DECLARE @AssignmentAttachmentsXML AS XML

SET @AssignmentAttachmentsXML = (
SELECT
    TaxId AS '@AssignmentId',
    AttachmentId AS '@AttachmentDbId',
    Folder AS '@Folder',
    IIAP AS '@IIAP',
    AttachmentName AS '@AttachmentName',
    IIAPDate AS '@IIAPDate',
    AddToAssignmentDate AS '@AttachmentAddedDate',
    AttachmentAddedBy AS '@AttachmentAddedBy',
    CentralPrintDate AS '@CentralPrintDate',
    PostToCoreDate AS '@PostToCoreDate'
FROM @TempAttachmentDataTable
FOR XML PATH('Attachment'), ROOT('Attachments'));

WITH XMLNAMESPACES ('http://MtwUiTaxDataSchema' AS "MTW")
UPDATE compas.tbTaxAssignmentSequence
    SET xmlAssignment.modify('insert sql:variable("@AssignmentAttachmentsXML") into (/MTW:MtwUiTax/MTW:Assignment)[1]')
FROM
compas.tbTaxAssignment 
    INNER JOIN
        compas.tbTaxAssignmentSequence
            ON
                compas.tbTaxAssignment.fkbintCurrentSequence = compas.tbTaxAssignmentSequence.bintId
where compas.tbTaxAssignment.bintId = @AssignmentId;

结果是这段代码在“附件”元素中插入了一个带有 xmlns="" 属性的 XML 元素。

<Attachments xmlns="">
  <Attachment AssignmentId="10166" AttachmentDbId="72" ...
  <Attachment AssignmentId="10166" AttachmentDbId="73" ...
  <Attachment AssignmentId="10166" AttachmentDbId="75" ...
  <Attachment AssignmentId="10166" AttachmentDbId="88" ...
  <Attachment AssignmentId="10166" AttachmentDbId="89" ...
  <Attachment AssignmentId="10166" AttachmentDbId="90" ...
</Attachments>

xmlns 属性中的空字符串会扰乱下游 XPATH 查询。

如何更新 FOR XML PATH 查询以创建没有 xmlns 属性的 XML,如下所示:

<Attachments>
  <Attachment AssignmentId="10166" AttachmentDbId="72" ...
  <Attachment AssignmentId="10166" AttachmentDbId="73" ...
  <Attachment AssignmentId="10166" AttachmentDbId="75" ...
  <Attachment AssignmentId="10166" AttachmentDbId="88" ...
  <Attachment AssignmentId="10166" AttachmentDbId="89" ...
  <Attachment AssignmentId="10166" AttachmentDbId="90" ...
</Attachments>

-- 示例测试脚本 Microsoft SQL Server 2016 - 13.0.1742.0 (X64) ---

CREATE TABLE AssignmentTable
    (
        bintId BIGINT NULL, 
        xmlAssignment XML NULL
    )
    INSERT INTO [dbo].[AssignmentTable]
               ([bintId]
               ,[xmlAssignment])
         VALUES (
            1, 
            '<MtwUiTax xmlns="http://MtwUiTaxDataSchema"><Assignment id="10404"><Stuff/></Assignment></MtwUiTax>')
    SELECT [xmlAssignment] FROM AssignmentTable
    ----------------------------------------------------
    GO
    CREATE TABLE AttachmentTable
    (
        bintId BIGINT NULL, 
        Attrib1 VARCHAR(20),
        Attrib2 VARCHAR(20),
        Attrib3 VARCHAR(20),
    )
    INSERT INTO [dbo].[AttachmentTable]
               ([bintId]
               ,[Attrib1]
               ,[Attrib2]
               ,[Attrib3])
         VALUES
               (1
               ,'Attachment 1'
               ,'Apple'
               ,'Red'),
               (2
               ,'Attachment 2'
               ,'Grape'
               ,'Purple'),
               (3
               ,'Attachment 3'
               ,'Pear'
               ,'Green')
    SELECT * FROM AttachmentTable
    ----------------------------------------------------
    GO
    DECLARE @AssignmentAttachmentsXML AS XML
    SET @AssignmentAttachmentsXML = (SELECT bintId AS '@Id',
                                            Attrib1 AS '@Attrib1',
                                            Attrib2 AS '@Attrib2',
                                            Attrib3 AS '@Attrib3'
                                        FROM AttachmentTable
                                        FOR XML PATH('Attachment'), ROOT('Attachments'));
    SELECT @AssignmentAttachmentsXML;
    WITH XMLNAMESPACES ('http://MtwUiTaxDataSchema' AS "MTW")
                    UPDATE AssignmentTable
                        SET xmlAssignment.modify('insert sql:variable("@AssignmentAttachmentsXML") into (/MTW:MtwUiTax/MTW:Assignment)[1]')
                    FROM
                        AssignmentTable
                    WHERE
                        bintId = 1
    SELECT [xmlAssignment] FROM AssignmentTable
    -- CLEAN UP ----------------------------------------
    DROP TABLE AttachmentTable
    DROP TABLE AssignmentTable
    ----------------------------------------------------

【问题讨论】:

  • 在提出问题时,您需要提供一个可重现的最小示例。请参考以下链接:stackoverflow.com/help/minimal-reproducible-example 请提供以下内容: (1) DDL 和样本数据填充,即 CREATE table(s) 加上 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 你的 SQL Server 版本 (SELECT @@version;)

标签: sql-server xml tsql xquery xml-namespaces


【解决方案1】:

只需在与稍后插入@AssignmentAttachmentsXML 的目标元素相同的命名空间中创建@AssignmentAttachmentsXML 的元素:

DECLARE @AssignmentAttachmentsXML AS XML

WITH XMLNAMESPACES (default 'http://MtwUiTaxDataSchema')
SELECT @AssignmentAttachmentsXML = (
SELECT
    TaxId AS '@AssignmentId',
    AttachmentId AS '@AttachmentDbId',
    Folder AS '@Folder',
    IIAP AS '@IIAP',
    AttachmentName AS '@AttachmentName',
    IIAPDate AS '@IIAPDate',
    AddToAssignmentDate AS '@AttachmentAddedDate',
    AttachmentAddedBy AS '@AttachmentAddedBy',
    CentralPrintDate AS '@CentralPrintDate',
    PostToCoreDate AS '@PostToCoreDate'
FROM @TempAttachmentDataTable
FOR XML PATH('Attachment'), ROOT('Attachments'));
.............

【讨论】:

    【解决方案2】:

    在您的回复中,您选择了变量@AssignmentAttachmentsXML 我正在为@AssignmentAttachmentsXML 分配一个值,该值稍后在xmlAssignment.modify 语句中使用。当我添加默认的 xmlnamespaces 时,以下“WITH”语句会产生语法错误。显然“SET”和“SELECT”对“WITH XMLNAMESPACES”的处理方式不同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2016-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多