使用名称空间更新SQL Server XML数据

问题描述

我有一个临时表,在其中汇编各种值。组装好这些值后,我想查询表以生成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;

结果是此代码在“ Attachments”元素中插入带有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
    ----------------------------------------------------

解决方法

只需在与稍后插入@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'));
.............
,

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...