【问题标题】:Insert From XML File从 XML 文件插入
【发布时间】:2017-06-03 05:52:46
【问题描述】:

我正在尝试使用 XML 文件更新客户表,但它没有将 XML 中的值提取到变量中以传递到表中。我得到的错误是“无法将值 NULL 插入到列 'EmailAddress' 中”,即使 EmailAddress 显然有一个值。我觉得我错过了一些非常简单的东西,但无法弄清楚。有什么想法吗?

USE MyGuitarShop

DECLARE @CustomerUpdate XML

SET @CustomerUpdate = 
    '<NewCustomers>
        <Customer EmailAddress="izzychan@yahoo.com" Password="" FirstName="Isabella" LastName="Chan" />
        <Customer EmailAddress="johnprine@gmail.com" Password="" FirstName="John" LastName="Prine" />
        <Customer EmailAddress="kathykitchen@sbcglobal.net" Password="" FirstName="Kathy" LastName="Kitchen" />
    </NewCustomers>';

INSERT Customers (EmailAddress, Password, FirstName, LastName)
    VALUES
    (
        @CustomerUpdate.value('(/NewCustomers/Customer/EmailAddress)[1]', 'varchar(255)'),
        @CustomerUpdate.value('(/NewCustomers/Customer/Password)[1]', 'varchar(60)'),
        @CustomerUpdate.value('(/NewCustomers/Customer/FirstName)[1]', 'varchar(60)'),
        @CustomerUpdate.value('(/NewCustomers/Customer/LastName)[1]', 'varchar(60)')        
    );

SELECT * FROM Customers

【问题讨论】:

    标签: sql sql-server xml tsql xpath


    【解决方案1】:

    我觉得我错过了一些非常简单的东西......

    是的,你是对的 :-D,你缺少 @ 来读取 属性-值:

    DECLARE @CustomerUpdate XML
    
    SET @CustomerUpdate = 
        '<NewCustomers>
            <Customer EmailAddress="izzychan@yahoo.com" Password="" FirstName="Isabella" LastName="Chan" />
            <Customer EmailAddress="johnprine@gmail.com" Password="" FirstName="John" LastName="Prine" />
            <Customer EmailAddress="kathykitchen@sbcglobal.net" Password="" FirstName="Kathy" LastName="Kitchen" />
        </NewCustomers>';
    
    SELECT
            @CustomerUpdate.value('(/NewCustomers/Customer/@EmailAddress)[1]', 'varchar(255)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@Password)[1]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@FirstName)[1]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@LastName)[1]', 'varchar(60)')        
    

    更新:一次性插入所有 &lt;Customer&gt;

    试试这个:

    DECLARE @Customers TABLE(EMailAddress VARCHAR(100),[Password] VARCHAR(100),FirstName VARCHAR(100),LastName VARCHAR(100));
    
    DECLARE @CustomerUpdate XML
    
    SET @CustomerUpdate = 
        '<NewCustomers>
            <Customer EmailAddress="izzychan@yahoo.com" Password="" FirstName="Isabella" LastName="Chan" />
            <Customer EmailAddress="johnprine@gmail.com" Password="" FirstName="John" LastName="Prine" />
            <Customer EmailAddress="kathykitchen@sbcglobal.net" Password="" FirstName="Kathy" LastName="Kitchen" />
        </NewCustomers>';
    
    INSERT INTO @Customers (EmailAddress, Password, FirstName, LastName)
    SELECT c.value('@EmailAddress', 'varchar(255)')
          ,c.value('@Password', 'varchar(60)')
          ,c.value('@FirstName', 'varchar(60)')
          ,c.value('@LastName', 'varchar(60)')        
    FROM @CustomerUpdate.nodes(N'/NewCustomers/Customer') AS A(c)
    
    SELECT * FROM @Customers
    

    【讨论】:

    • 太棒了!我什至完全没有意识到我需要拥有它。非常感谢您指出这一点。
    【解决方案2】:

    此代码现在可以完美运行。

        USE MyGuitarShop
    
    DECLARE @CustomerUpdate XML
    
    SET @CustomerUpdate = 
        '<NewCustomers>
            <Customer EmailAddress="izzychan@yahoo.com" Password="" FirstName="Isabella" LastName="Chan" />
            <Customer EmailAddress="johnprine@gmail.com" Password="" FirstName="John" LastName="Prine" />
            <Customer EmailAddress="kathykitchen@sbcglobal.net" Password="" FirstName="Kathy" LastName="Kitchen" />
        </NewCustomers>';
    
    INSERT Customers (EmailAddress, Password, FirstName, LastName)
        VALUES
        (
            @CustomerUpdate.value('(/NewCustomers/Customer/@EmailAddress)[1]', 'varchar(255)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@Password)[1]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@FirstName)[1]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@LastName)[1]', 'varchar(60)')       
        );
    
    INSERT Customers (EmailAddress, Password, FirstName, LastName)
        VALUES
        (
            @CustomerUpdate.value('(/NewCustomers/Customer/@EmailAddress)[2]', 'varchar(255)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@Password)[2]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@FirstName)[2]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@LastName)[2]', 'varchar(60)')       
        );
    
    INSERT Customers (EmailAddress, Password, FirstName, LastName)
        VALUES
        (
            @CustomerUpdate.value('(/NewCustomers/Customer/@EmailAddress)[3]', 'varchar(255)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@Password)[3]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@FirstName)[3]', 'varchar(60)'),
            @CustomerUpdate.value('(/NewCustomers/Customer/@LastName)[3]', 'varchar(60)')       
        );
    
    SELECT * FROM Customers
    

    【讨论】:

    • 嗯,这可能完美地工作,但没有必要复制你的代码并使用硬编码的位置(如[2])。查看我更新的答案,了解使用 .nodes() 从 XML 中获取派生表的方法。
    • 那就更好了。我还不够先进,不知道如何做到这一点,所以我很高兴你向我展示了这一点。这将使这个和未来的代码更简单。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多