如何在XML中的表中插入空值?

时间:2018-01-31 05:42:21

标签: sql-server stored-procedures

我有一个表格,其中有几列(IntBool)为nullable。我有一个存储过程,它将XML作为输入参数。我试图传递其中一些列的空值,但它插入0而不是null。

declare @temp XML;
set @temp = '
<ArrayOfTestFileEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TestFileEntity>
    <TestId xsi:nil="true" />
    <MainTestNo xsi:nil="true" />
    <TestCode xsi:nil="true" />
    <TestCode1 />
    <FlgTemp xsi:nil="true" />
  </TestFileEntity>
</ArrayOfTestFileEntity>'


    declare @xmlInput as XML = @temp;
    declare @xmlOutput as XML;

BEGIN
    SET NOCOUNT ON;

    DECLARE @insertedTable table(Id int); 

    MERGE INTO Test AS Trg USING (
    SELECT
        d.x.value('TestId[1]', 'int') AS TestId,
        d.x.value('MainTestNo[1]', 'int') AS MainTestNo,
        d.x.value('TestCode[1]', 'int') AS TestCode,
        d.x.value('TestCode1[1]', 'int') AS TestCode1,
        d.x.value('FlgTemp[1]', 'bit') AS FlgTemp

    FROM
        @xmlInput.nodes('/ArrayOfTestFileEntity/TestFileEntity') AS d(x)
    ) AS Src ON Trg.Id = Src.Id
        WHEN Matched THEN
            UPDATE SET
                Trg.TestId = Src.TestId,
                Trg.MainTestNo = Src.MainTestNo,
                Trg.TestCode = Src.TestCode,
                Trg.TestCode1 = Src.TestCode1,
                Trg.FlgTemp = Src.FlgTemp,

            WHEN NOT matched BY TARGET THEN 
                INSERT 
                    ([TestId]
                    ,[MainTestNo]
                    ,[TestCode]
                    ,[TestCode1]
                    ,[FlgTemp])
                VALUES
                    (Src.TestId,
                    Src.MainTestNo,
                    Src.TestCode,
                    Src.TestCode1,
                    Src.FlgTemp)
        OUTPUT INSERTED.Id INTO @insertedTable;

        set @xmlOutput = (SELECT * FROM @insertedTable for XML AUTO, ROOT('RowsUpserted'));
        select @xmlOutput;
END

1 个答案:

答案 0 :(得分:1)

当您从xml中选择值时,基本上需要使用[not(@xsi:nil = "true")]

所以我已经在你的查询中应用了它。因此,如果您观察到xml,您会注意到我为<TestCode1>标记添加了值16,并保留了标记的其余部分。

declare @temp XML;
set @temp = '
<ArrayOfTestFileEntity xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <TestFileEntity>
    <TestId xsi:nil="true" />
    <MainTestNo xsi:nil="true" />
    <TestCode xsi:nil="true" />
    <TestCode1>16</TestCode1>
    <FlgTemp xsi:nil="true" />
  </TestFileEntity>
</ArrayOfTestFileEntity>'


DECLARE @xmlInput as XML = @temp;

--MERGE INTO Test AS Trg USING (
SELECT
    d.x.value('TestId[1][not(@xsi:nil = "true")]', 'int') AS TestId,
    d.x.value('MainTestNo[1][not(@xsi:nil = "true")]', 'int') AS MainTestNo,
    d.x.value('TestCode[1][not(@xsi:nil = "true")]', 'int') AS TestCode,
    d.x.value('TestCode1[1][not(@xsi:nil = "true")]', 'int') AS TestCode1,
    d.x.value('FlgTemp[1][not(@xsi:nil = "true")]', 'bit') AS FlgTemp

FROM
    @xmlInput.nodes('/ArrayOfTestFileEntity/TestFileEntity') AS d(x)