【问题标题】:SQL to generate an XML生成 XML 的 SQL
【发布时间】:2019-03-11 23:44:37
【问题描述】:

我遇到了一个 xml 创建挑战。

我的挑战是从具有以下定义的数据表中生成 xml

marketingCampaign

    id      INT
    campaign_code
    campaign_start_date
    activity_code
    target_email_address
    comms

此 xml 将被转发到第 3 方应用程序,并期望以下格式。

<xml  ....>
    <marketCampaign type='C'>
        <campaign>
            <campaign_code/>
            <campaign_start_date/>
        <campaign>
    </marketCampaign> 
    <marketCampaign type='A'>
        <activity>
            <activity_code/> 
            <campaign_code/>
        <activity>
    </marketCampaign> 
    <marketCampaign type='M'>
        <message>
            <activity_code/> 
            <target_email_address/>
        <message>
    </marketCampaign> 
    </xml>

我想使用纯 SQL 脚本(如果可能的话)来限制这一点,所以我使用了“FOR XML PATH”功能。我尝试了不同的组合来实现上述格式,而没有编写多个 sql 语句,但没有成功。我已经设法在下面生成了 xml,但第 3 方应用程序拒绝了这种格式。

<xml  ....>
<marketCampaign type='C'>
    <campaign>
        <campaign_code/>
        <campaign_start_date/>
        <activity>
            <activity_code/> 
            <campaign_code/>
            <message>
                <activity_code/> 
                <target_email_address/>
            <message>
        </activity>
    <campaign>
</marketCampaign> 
</xml>

我的问题是可以用单个 SQL 完成上述 xml 格式,实现这一点的最有效方法是什么?

我可以编写一个冗长的脚本来根据第 3 方的要求生成 xml 格式,但是如果可能,我会尽量避免使用该选项。

更新

下面是我尝试的当前 SQL

SELECT DISTINCT
    'C' AS "@resultsType",
    c.campaign_code AS "campaign/campaign_code",
    CONVERT(DATE, campaign_start_date, 102) AS "campaign/campaign_start_date",
    CONVERT(DATE, GETDATE(), 102) AS "campaign/authorizeDate", 
    'A' AS "marketCampaign/@resultsType",
    c.activity_code AS "activity/code",
    c.campaign_code AS "activity/campaign_code",
    'M' AS "marketCampaign/@resultsType",
    c.activity_code AS "message/activityCode",
    c.target_email_address AS "message/target_email_address",
    c.comms AS "message/fileText"
FROM
    dev.campaign.marketting_data c
FOR XML PATH('marketCampaign'), ROOT('xml')

问题是我不想多次重复“resultType=C”,除非它是一组新的campaign_code,同样的规则适用于activity_code

【问题讨论】:

  • XML 只是文本,因此您可以根据需要使用文本函数将它们全部粘贴在一起
  • 我看到格式有点不同。请贴出您使用的FOR XML T-SQL。
  • 你可以做一些不靠谱的选择,我猜...例如:SELECT (SELECT '@type' = 'C', (SELECT campaign_code, campaign_start_date FOR XML PATH('campaign'), TYPE) FOR XML PATH ('marketCampaign'), TYPE), (SELECT '@type' = 'A', etc...) FROM myTable FOR XML PATH ('xml');
  • @Nick.McDermaid 我已经用我目前完成的示例代码更新了我的原始帖子。
  • 注意:如果喜欢这种格式,也可以写成SELECT (SELECT '@type' = 'C', 'campaign/campaign_code' = campaign_code, 'campaign/campaign_start_date' = campaign_start_date FOR XML PATH ('marketCampaign'), TYPE), (SELECT '@type' = 'A', 'activity/activity_code' = activity_code... etc) FROM mytable FOR XML PATH ('xml');

标签: sql sql-server xml tsql ssis


【解决方案1】:

快速更新

我使用了其中一个建议,它似乎可以解决问题。我确实尝试过 LINQ to XML,但是我的客户在维护代码时可能会遇到一些挑战,所以我尽量保持简单。

非常感谢大家的帮助。

我使用了下面的 SQL 脚本。

  SELECT
    -- Campaign
    ( SELECT 
          '@Type'                           = 'C'
         ,'campaign/campaign_code'          = mc.campaign_code
         ,'campaign/camapaign_start_date'   = mc.camapaign_start_date
         FOR XML PATH('marketCampaign'), TYPE),
    -- Activity
    (SELECT
         '@Type'                = 'A'
        ,'activity/activity_code'   = mc.activity_code
        ,'activity/campaign_code'   = mc.campaign_code
        FOR XML PATH('marketCampaign'), TYPE),
    -- Message
    (SELECT
        '@Type'                  = 'I'
        ,'message/activity_code'         = mc.activity_code
        ,'message/target_email_address'  = ISNULL(mc.comms_supporter_id,'')
        ,'message/email_content'         =  '===TEST ===='
        ,'message/creationDate'          = format( DATEADD(month, -3,  getdate()), 'dd/MM/yyyy')  
        ,'message/time'                  = '00:00:00'
        FOR XML PATH('marketCampaign'), TYPE)
 FROM marketingCampaign mc
FOR XML PATH(''), ROOT('xml')

【讨论】:

    猜你喜欢
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2010-09-20
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    • 1970-01-01
    相关资源
    最近更新 更多