从数据库读取值并更新现有的xml

时间:2017-04-07 06:03:20

标签: sql-server xml

使用SQL Server 2008和表有一些像这样的值:

EMPN ENAME      JOB       HIREDATE
---- ---------- --------- -----------
7341 SMITH      CLERK     17-DEC-1980
7482 ALLEN      SALESMAN  20-FEB-1981

我的XML位于共享文件夹

<employees>
    <employee>
        <empno>7369</empno>
        <ename>SMITH</ename>
        <job>CLERK</job>
        <hiredate>17-DEC-1980</hiredate>
    </employee>    
    <employee>
        <empno>7499</empno>
        <ename>ALLEN</ename>
        <job>SALESMAN</job>
        <hiredate>20-FEB-1981</hiredate>
    </employee>
</employees>

现在需要根据数据库值(EMPN)

更改现有的XML

我们该怎么做?

2 个答案:

答案 0 :(得分:2)

你的问题并不是很清楚......

起初有些提示:

您显示的表格数据和您提供的XML不包含相同的ID,因此我假设您需要将新员工添加为新的子节点:

DECLARE @existingXML XML=
'<employees>
  <employee>
    <empno>7369</empno>
    <ename>SMITH</ename>
    <job>CLERK</job>
    <hiredate>17-DEC-1980</hiredate>
  </employee>
  <employee>
    <empno>7499</empno>
    <ename>ALLEN</ename>
    <job>SALESMAN</job>
    <hiredate>20-FEB-1981</hiredate>
  </employee>
</employees>';

SET LANGUAGE ENGLISH;
DECLARE @tmpTable TABLE(MPN INT,ENAME VARCHAR(100),JOB VARCHAR(100),HIREDATE DATE);
INSERT INTO @tmpTable VALUES
 (7341,'SMITH','CLERK','17-DEC-1980')
,(7482,'ALLEN','SALESMAN','20-FEB-1981');

DECLARE @NewXml XML=
(
SELECT
    (
    SELECT e.MPN AS [empno]
          ,e.ENAME AS [ename]
          ,e.JOB AS [job]
          ,e.HIREDATE AS [hiredate]
    FROM @tmpTable AS e
    FOR XML PATH('employee'),TYPE
    ) AS NewXML
);
SET @existingXML.modify(N'insert sql:variable("@NewXML") as last into (/employees)[1]');

SELECT @existingXML;

如果你需要同步一个表和XML的数据,我会把整个事情粉碎到一个派生表,对行方式数据使用一些MERGE方法并重建从头开始的XML。

答案 1 :(得分:0)

在这种方法中,我们:

  • 过滤掉需要更新的记录的XML节点
  • 附加到从更新记录生成的XML节点

我们避免使用XML DML语句。

SELECT *
INTO #Employees
FROM (VALUES
(7341, 'SMITH',      'CLERK'    , CONVERT(DATE,'17-DEC-1980')),
(7482, 'ALLEN',      'SALESMAN' , CONVERT(DATE, '20-FEB-1981'))
)v(Empn, Ename, Job, HireDate)

-- This is your existing XML data, which contains many <employee> nodes
DECLARE @Xml XML = 
'
<employees>
    <employee>
        <empno>7341</empno>
        <ename>SMITH</ename>
        <job>CLERK</job>
        <hiredate>17-DEC-1980</hiredate>
    </employee>    
    <employee>
        <empno>7482</empno>
        <ename>ALLEN</ename>
        <job>SALESMAN</job>
        <hiredate>20-FEB-1981</hiredate>
    </employee>
    <employee>
        <empno>111</empno>
        <ename>JAMES</ename>
        <job>TESTER</job>
        <hiredate>20-FEB-1999</hiredate>
    </employee>
    <employee>
        <empno>222</empno>
        <ename>BOB</ename>
        <job>TESTER</job>
        <hiredate>20-FEB-1999</hiredate>
    </employee>
</employees>'


SELECT node.query('.')
FROM (
            -- Return only those nodes from XML, which do not match any records in #Employees table
            SELECT   t.e.query('.')
            FROM @Xml.nodes('/employees/employee') t(e)
            WHERE t.e.value('(empno)[1]', 'INT') NOT IN (
                SELECT Empn
                FROM #Employees
            )

            UNION ALL

            SELECT (
                    SELECT   [empno] = Empn
                            ,[ename] = Ename
                            ,[job] = Job
                            ,[hiredate] = HireDate
                    FROM #Employees
                    WHERE Empn = e.Empn
                    FOR XML PATH('employee'), TYPE
            )
            FROM #Employees e
) t(node)
FOR XML PATH(''), ROOT('employees')