【问题标题】:Import 'xml' node into sql sever dynamically with conditional statement使用条件语句将'xml'节点动态导入sql server
【发布时间】:2014-09-12 07:26:33
【问题描述】:

这与这个问题有关: Import 'xml' into Sql Server

您将如何处理可选的 XML 节点,假设“IsFixed”是一个可选节点,它存在于一个文件中而在另一个文件中不存在,如何在代码中放入条件以不执行“ Events.value" 并避免出现 Null 列?

DECLARE @XML XML = '
<EventSchedule>
    <Event Uid="2" Type="Main Event">
        <EventKind>MainEvent</EventKind>
        <Fields>
            <Parameter Name="Type" Value="TV_Show"/>
            <Parameter Name="Name" Value="The Muppets"/>
            <Parameter Name="Duration" Value="00:30:00"/>
        </Fields>
    </Event>
    <Event Uid="3" Type="Secondary Event">
        <EventKind>SecondaryEvent</EventKind>
        <Fields>
            <Parameter Name="Type" Value="TV_Show"/>
            <Parameter Name="Name" Value="The Muppets II"/>
            <Parameter Name="Duration" Value="00:30:00"/>
        </Fields>
    </Event>
</EventSchedule>'

如果 IsFixed 节点不存在,则不要执行粗线:

SELECT
    EventUID = Events.value('@Uid', 'int'),
    EventType = Events.value('@Type', 'varchar(20)'),
    ***EventIsFixed = Events.value('(IsFixed)[1]', 'varchar(20)'),***
    EventKind = Events.value('(EventKind)[1]', 'varchar(20)'),
    ParameterType = Events.value('(Fields/Parameter[@Name="Type"]/@Value)[1]', 'varchar(20)'),
    ParameterName = Events.value('(Fields/Parameter[@Name="Name"]/@Value)[1]', 'varchar(20)'),
    ParameterDuration = Events.value('(Fields/Parameter[@Name="Duration"]/@Value)[1]', 'varchar(20)')
FROM
    @XML.nodes('/EventSchedule/Event') AS XTbl(Events)

我尝试在 SELECT 语句中使用 CASE WHEN 但没有成功:

SELECT
    EventUID = Events.value('@Uid', 'int'),
    EventType = Events.value('@Type', 'varchar(20)'),
    CASE 
        WHEN Events.value('(IsFixed)[1]', 'varchar(20)') IS NOT NULL
        THEN ''
    END AS EventIsFixed,
    EventKind = Events.value('(EventKind)[1]', 'varchar(20)'),
    ParameterType = Events.value('(Fields/Parameter[@Name="Type"]/@Value)[1]', 'varchar(20)'),
    ParameterName = Events.value('(Fields/Parameter[@Name="Name"]/@Value)[1]', 'varchar(20)'),
    ParameterDuration = Events.value('(Fields/Parameter[@Name="Duration"]/@Value)[1]', 'varchar(20)')
FROM
    @XML.nodes('/EventSchedule/Event') AS XTbl(Events)

上面的代码仍然创建了一个作为 EventIsFixed 的空值列(输出表)。

EventUID    EventType   EventIsFixed    EventKind   ParameterType   ParameterName   ParameterDuration
2           Main Event                  MainEvent      TV_Show      The Muppets     00:30:00
3           Secondary Event             SecondaryEvent  TV_Show     The Muppets II  00:30:00

我想要做的是当 XML 节点存在时在表中有列,而当 XML 节点不存在时(动态地)根本没有列,如何?

【问题讨论】:

    标签: sql xml select case-when


    【解决方案1】:

    使用exist()检查IsFixed是否存在。

    IF @XML.exist('/EventSchedule/Event/IsFixed') = 1
    BEGIN
      SELECT
          EventUID = Events.value('@Uid', 'int'),
          EventType = Events.value('@Type', 'varchar(20)'),
          EventIsFixed = Events.value('(IsFixed)[1]', 'varchar(20)'),
          EventKind = Events.value('(EventKind)[1]', 'varchar(20)'),
          ParameterType = Events.value('(Fields/Parameter[@Name="Type"]/@Value)[1]', 'varchar(20)'),
          ParameterName = Events.value('(Fields/Parameter[@Name="Name"]/@Value)[1]', 'varchar(20)'),
          ParameterDuration = Events.value('(Fields/Parameter[@Name="Duration"]/@Value)[1]', 'varchar(20)')
      FROM
          @XML.nodes('/EventSchedule/Event') AS XTbl(Events)
    END
    ELSE
    BEGIN
      SELECT
          EventUID = Events.value('@Uid', 'int'),
          EventType = Events.value('@Type', 'varchar(20)'),
          EventKind = Events.value('(EventKind)[1]', 'varchar(20)'),
          ParameterType = Events.value('(Fields/Parameter[@Name="Type"]/@Value)[1]', 'varchar(20)'),
          ParameterName = Events.value('(Fields/Parameter[@Name="Name"]/@Value)[1]', 'varchar(20)'),
          ParameterDuration = Events.value('(Fields/Parameter[@Name="Duration"]/@Value)[1]', 'varchar(20)')
      FROM
          @XML.nodes('/EventSchedule/Event') AS XTbl(Events)
    END
    

    【讨论】:

    • 感谢 Mikael 的快速响应。一个后续问题是我有许多 xml 文件,其中 30 个节点“必需”和 60 个节点“可选”,因此将 if-else 语句用于 60 个可选节点(即动态出现在 xml 文件中)将需要 60 个! (60 阶乘) = 8.3209871e+81 if-else 案例。有没有其他方法可以解决这个问题?谢谢。
    • @Tempo 然后你需要解析 XML 并动态构建查询。
    • 您能否给我更多提示或示例代码,如您提供的上述内容。由于数据库中已经构建了其他逻辑,我仍然必须构建表。谢谢。
    • @Tempo 你可以看看here的例子。
    • @Tempo 这是另一个。 stackoverflow.com/questions/25640784/…
    猜你喜欢
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2017-05-01
    • 2014-08-02
    • 2018-07-19
    • 1970-01-01
    相关资源
    最近更新 更多