【问题标题】:SQL Server: update table from xml stringSQL Server:从 xml 字符串更新表
【发布时间】:2014-06-11 15:54:39
【问题描述】:

这是我第一次在 SQL 中使用 XML 输入。

我创建了以下过程,将我的 XML 字符串中的所有记录插入到我的表中,到目前为止效果很好。

有人可以告诉我如何更改它,以便它只插入一条新记录,如果itemID(我的 XML 中的每条记录也有这个)在我的表中尚不存在,列 itemID - 否则它应该使用 XML 中的新数据更新现有记录。

我一般都知道如何使用IF NOT EXISTSUPDATE,但不确定如何使用XML 字符串作为输入来实现这一点。

我的程序(到目前为止):

ALTER PROCEDURE [dbo].[editor_UpdateQuestions]
    @xml xml
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO editor_Questions
        (
            categoryID,
            question,
            sortID,
            modDate,
            modBy       
        )
    SELECT  ParamValues.x1.value('categoryID[1]', 'int'),
            ParamValues.x1.value('question[1]', 'nvarchar(1000)'),
            ParamValues.x1.value('sortID[1]', 'int'),
            GETDATE(),
            ParamValues.x1.value('modBy[1]', 'varchar(50)')
    FROM    @xml.nodes('/ranks/item') AS ParamValues(x1)

END

XML 输入示例:

<ranks>
    <item><itemID>25</itemID><categoryID>1</categoryID><question>some text</question><sortID>1</sortID><modBy>abc</modBy></item>
    <item><itemID>12</itemID><categoryID>1</categoryID><question>some text 2</question><sortID>2</sortID><modBy>abc</modBy></item>
    <item><itemID>9</itemID><categoryID>1</categoryID><question>some text 3</question><sortID>3</sortID><modBy>abc</modBy></item>
</ranks>

提前非常感谢您提供的任何帮助,蒂姆。

【问题讨论】:

    标签: sql sql-server xml stored-procedures


    【解决方案1】:
    ;WITH new_Questions AS (
        SELECT  ParamValues.x1.value('itemID[1]'    , 'int'           ) AS itemID,
                ParamValues.x1.value('categoryID[1]', 'int'           ) AS categoryID,
                ParamValues.x1.value('question[1]'  , 'nvarchar(1000)') AS question,
                ParamValues.x1.value('sortID[1]'    , 'int'           ) AS sortID,
                GETDATE()                                               AS date,
                ParamValues.x1.value('modBy[1]'     , 'varchar(50)'   ) AS modBy
        FROM    @xml.nodes('/ranks/item') AS ParamValues(x1)
    )
    MERGE INTO editor_Questions AS old
    USING new_Questions AS new
      ON (new.itemID = old.itemID)
    WHEN MATCHED THEN UPDATE SET
      old.categoryID = new.categoryID,
      old.question   = new.question  ,
      old.date       = new.date      ,
      old.sortID     = new.sortID    ,
      old.modBy      = new.modBy
    WHEN NOT MATCHED THEN 
      INSERT (    itemId,    categoryID,    question,    date,    sortID,    modBy)
      VALUES (new.itemId,new.categoryID,new.question,new.date,new.sortID,new.modBy);
    

    【讨论】:

    • 非常感谢您的快速回复!你能给我一些关于如何使用它的指导吗?这会取代整个查询吗?
    • 用它代替你的 INSERT 语句。此 MERGE 将插入或更新每一行,具体取决于它是否可以匹配 itemID
    • 非常感谢。我会尝试一下,然后再回来。
    • 这非常有效 - 只需从插入中删除 itemID,因为这是自动生成的并将日期更改为 modDate 以与我的列名一致。非常感谢这个 - 大帮助! :)
    【解决方案2】:

    您可以使用如下合并语句

    MERGE editor_Questions AS Target
        USING (
        SELECT  ParamValues.x1.value('categoryID[1]', 'int') AS categoryID,
                ParamValues.x1.value('question[1]', 'nvarchar(1000)') AS question,
                ParamValues.x1.value('sortID[1]', 'int') AS sortID,
                GETDATE() AS [Date],
                ParamValues.x1.value('modBy[1]', 'varchar(50)') AS ModBy
        FROM    @xml.nodes('/ranks/item') AS ParamValues(x1)
    
        ) AS SOURCE
        ON Target.categoryID =SOURCE.categoryID
        WHEN MATCHED THEN 
        UPDATE SET Target.question = Source.question,
                Target.sortID = Source.sortID,
                Target.modDate=Source.[Date],
                Target.ModBy = Source.ModBy
        WHEN NOT MATCHED  THEN
        INSERT 
            (
                categoryID,
                question,
                sortID,
                modDate,
                modBy       
            )
        VALUES  (categoryID,question,sortID,[Date],ModBy);
    

    【讨论】:

    • 谢谢 - 我也会检查一下!
    • 我用 modDate 替换了日期,因为那是我的列名,并将 ModBy 更改为 modBy,但它没有更新任何内容。
    • 更新:我认为您只是在第一个语句中丢失了 categoryID,这就是失败的原因。
    • 想通了。如果您将 itemID 添加到您的选择并将源引用更改为 itemID,您的解决方案也可以正常工作,因为这是唯一标识符。
    猜你喜欢
    • 2012-05-10
    • 2023-04-06
    • 2017-06-02
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多