如何从XML检索值并将它们插入到动态SQL语句中?

时间:2014-03-05 22:25:22

标签: sql sql-server xml sql-server-2012

我正在尝试使用一些XML并在动态SQL查询中使用它的值。

所以我的XML看起来像这样:

DECLARE @xmlTest xml;
SET @xmlTest = '<Mapping>
    <Element name="FirstTable">
        <Column>
            <Source>SourceColumn1</Source>
            <Destination>DestinationColumn1</Destination>
        </Column>
        <Column>
            <Source>SourceColumn2</Source>
            <Destination>DestinationColumn2</Destination>
        </Column>
        <Column>
            <Source>SourceColumn3</Source>
            <Destination>DestinationColumn3</Destination>
        </Column>           
    </Element>
    <Element name="SecondTable">
            <Column>
            <Source>SourceColumn4</Source>
            <Destination>DestinationColumn4</Destination>
        </Column>
        <Column>
            <Source>SourceColumn5</Source>
            <Destination>DestinationColumn5</Destination>
        </Column>
    </Element>
</Mapping>'

使用此XML,我想基于Element“name”属性将数据从一个表映射到另一个表。根据“名称”在数据库中设置了表格(例如:数据库包含名为“FirstTable”和“SecondTable”的表)

数据库中还有其他表包含<Column>元素中的字段。这些是我想从中获取某些列并将其复制到Element名称表中的表。这些表只包含我希望移动到其他表中的原始数据(如“FirstTable”和“SecondTable”)。

所以我试图做的一个SQL语句的例子就是:

INSERT INTO [FirstTable](DestinationColumn1, DestinationColumn2, DestinationColumn3)
SELECT (SourceColumn1, SourceColumn2, SourceColumn3)
FROM [RawDataTable]

我需要执行此语句以插入到有<Column>个元素的每个表中。

如何从XML和SQL查询中获取所需的值?此外,为XML中的每个<Element>运行此SQL语句的最佳方法是什么?注意:可能会有不同数量的<Column>元素,因此我选择使用动态SQL。

由于

1 个答案:

答案 0 :(得分:2)

如果C#代码生成XML,它也可以更容易地生成SQL语句。这可能不会有效,但你可以使用像

这样的东西
DECLARE @xmlTest xml;
SET @xmlTest = '<Mapping>
    <Element name="FirstTable">
        <Column>
            <Source>SourceColumn1</Source>
            <Destination>DestinationColumn1</Destination>
        </Column>
        <Column>
            <Source>SourceColumn2</Source>
            <Destination>DestinationColumn2</Destination>
        </Column>
        <Column>
            <Source>SourceColumn3</Source>
            <Destination>DestinationColumn3</Destination>
        </Column>           
    </Element>
    <Element name="SecondTable">
        <Column>
            <Source>SourceColumn4</Source>
            <Destination>DestinationColumn4</Destination>
        </Column>
        <Column>
            <Source>SourceColumn5</Source>
            <Destination>DestinationColumn5</Destination>
        </Column>
    </Element>
</Mapping>'

;With Map
As
(
    SELECT
         x.value('../@name', 'nvarchar(50)') TableName
        ,x.value('Source[1]', 'nvarchar(50)') SourceColumn
        ,x.value('Destination[1]', 'nvarchar(50)') DestinationColumn
    from
        @xmlTest.nodes('/Mapping/Element/Column') T(x)
)
select distinct 'INSERT INTO [' + M.TableName + '] (' + Left(DC.DestinationColumns, Len(DC.DestinationColumns) - 1) + ') SELECT (' + Left(SC.SourceColumns, Len(SC.SourceColumns) - 1) + ') FROM [RawDataTable]' as SQLs
from Map M
cross apply (
    select
        CONVERT(VARCHAR(255), SourceColumn) + ',' AS [text()]
    from
        Map M2
    where
        M.TableName = M2.TableName
    FOR XML PATH('')
) SC(SourceColumns)
cross apply (
    select
        CONVERT(VARCHAR(255), DestinationColumn) + ',' AS [text()]
    from
        Map M2
    where
        M.TableName = M2.TableName
    FOR XML PATH('')
) DC(DestinationColumns)