sql查询从xml中提取数据

时间:2015-03-13 21:51:57

标签: sql-server xml

我在查询存储在sql 2012中的xml数据时遇到问题..下面是我要提取“LicensingWindowStart”值的节点树。

 <sol>
    <so>
      <v>0</v>
      <t>BusinessMetadata</t>
      <al>
        <a k="Price">
          <v>4.99</v>
        </a>
        <a k="Currency">
          <v>US</v>
        </a>
      </al>
      <sol />
    </so>
    <so>
      <v>0</v>
      <t>RightsMetadata</t>
      <al>
        <a k="LicensingWindowStart">
          <v>2008-09-12T00:00:00</v>
        </a>
        <a k="LicensingWindowEnd">
          <v>2015-09-19T23:59:59</v>
        </a>
        <a k="AvailabilityWindowStart">
          <v>2008-09-12T00:00:00</v>
        </a>
        <a k="AvailabilityWindowEnd">
          <v>2015-09-19T23:59:59</v>
        </a>
        <a k="NewReleaseWindow">
          <v>0</v>
        </a>
        <a k="MaximumViewingLimit">
          <v>10080</v>
        </a>
      </al>
      <sol />
    </so>
    <so xsi:type="ListingsItem">
      <v>0</v>
      <id>test/1080i25spts3NascarSchool3mints_feature</id>
      <t>feature</t>
      <n>Nascar_Racing_School_feature</n>
      <fl>
        <f>HD</f>
      </fl>
      <al>
        <a k="AssetId">
          <v>1080i25spts3NascarSchool3mints_feature</v>
        </a>
        <a k="StreamFormat">
          <v>rtp</v>
        </a>
        <a k="RuntimeSeconds">
          <v>175</v>
        </a>
        <a k="DefaultLanguage">
          <v>en</v>
        </a>
        <a k="Content">
          <v t="FileName">1080i25-spts-3-NascarSchool-3min.ts</v>
          <v t="SizeInBytes" />
          <v t="NetworkType" />
          <v t="KBPS" />
          <v t="PlayReady" />
          <v t="WebInitiatorUrl" />
          <v t="LicenseServerProxyUrl" />
          <v t="Type" />
          <v t="PitchedFilename">1080i25-spts-3-NascarSchool-3min.ts</v>
        </a>
        <a k="ProcessContent">
          <v t="SourceFilePath">1080i25-spts-3-NascarSchool-3min.ts</v>
          <v t="DestinationDirectory">Media/e9959908-dabc-4691-a190-a30668d5c797</v>
          <v t="HD">true</v>
          <v t="HDCPDisable">false</v>
          <v t="Status">true</v>
          <v t="ServiceInformationID">e9959908-dabc-4691-a190-a30668d5c797</v>
          <v t="AssetType">feature</v>
          <v t="StreamFormat">rtp</v>
        </a>
      </al>
      <sol />
      <rl>
        <r>MPAA,R</r>
      </rl>
    </so>
    <so xsi:type="ListingsItem">
      <v>0</v>
      <id>test/1080i25spts3NascarSchool3mintsposter</id>
      <t>poster</t>
      <n>Nascar_Racing_School_poster</n>
      <fl>
        <f>SD</f>
      </fl>
      <al>
        <a k="AssetId">
          <v>1080i25spts3NascarSchool3mintsposter</v>
        </a>
        <a k="DefaultLanguage">
          <v>en</v>
        </a>
        <a k="Content">
          <v t="FileName">nascarschool_new.jpg</v>
          <v t="SizeInBytes" />
          <v t="NetworkType" />
          <v t="KBPS" />
          <v t="PlayReady" />
          <v t="WebInitiatorUrl" />
          <v t="LicenseServerProxyUrl" />
          <v t="Type" />
          <v t="PitchedFilename">nascarschool_new.jpg</v>
        </a>
        <a k="OrigFileLoc">
          <v>147\106\test-HD30002\Poster\nascarschool_new.jpg</v>
        </a>
        <a k="PosterUrl">
          <v>/posters/147/106/test-HD30002/Poster/nascarschool_new__{0}.jpg</v>
        </a>
      </al>
      <sol />
      <rl>
        <r>MPAA,R</r>
      </rl>
    </so>
  </sol>

我使用以下查询: (convert(xml,[columnname]))。query('/ SO / SOL / AL / LicensingWindowStart / V / text()')LicenseStartDate

有人可以帮我吗?

1 个答案:

答案 0 :(得分:1)

我将这个例子用于工作......您可能需要修改它以从表列中提取值,或者您真正想要或需要做的任何事情:

    DECLARE @xml xml;
    SET @xml = '
    <so>
      <v>0</v>
      <t>RightsMetadata</t>
      <al>
        <a k="LicensingWindowStart">
          <v>2014-09-12T00:00:00</v>
        </a>
      </al>
      <sol />
    </so>'

    SELECT CONVERT(datetime, 
               CONVERT(nvarchar(1000), 
                   @xml.query('(/so/al/a[@k=''LicensingWindowStart''])/v/text()')
               )
           ) AS LicensingWindowStart;

前两个语句(DECLARE和SET)只是设置了测试数据。

SELECT查询xml变量以查找适当的节点,然后将该值转换为日期时间。由于不允许直接xml到datetime的转换,我首先转换为nvarchar(1000),然后将THAT转换为datetime。结果被选中。

由于我不确定你要做什么(你没有为上下文提供任何架构或其他信息),我希望这足以帮助你找到解决问题的正确方向。 / p>

回到上面的示例,我创建了一个物理表,其中包含一个非xml列,其中包含xml作为字符串(不是最佳实践),并为您提供了此测试:

    CREATE TABLE TextXmlTable (ColumnName nvarchar(1000));
    INSERT INTO TextXmlTable (ColumnName)
    VALUES ('
<sol>
    <so>
        <v>0</v>
        <t>BusinessMetadata</t>
        <al>
            <a k="Price">
                <v>4.99</v>
            </a>
            <a k="Currency">
                <v>US</v>
            </a>
        </al>
        <sol />
    </so>
    <so>
        <v>0</v>
        <t>RightsMetadata</t>
        <al>
            <a k="LicensingWindowStart">
                <v>2008-09-12T00:00:00</v>
            </a>
            <a k="LicensingWindowEnd">
                <v>2015-09-19T23:59:59</v>
            </a>
            <a k="AvailabilityWindowStart">
                <v>2008-09-12T00:00:00</v>
            </a>
            <a k="AvailabilityWindowEnd">
                <v>2015-09-19T23:59:59</v>
            </a>
            <a k="NewReleaseWindow">
                <v>0</v>
            </a>
            <a k="MaximumViewingLimit">
                <v>10080</v>
            </a>
        </al>
        <sol />
    </so>
    <so type="ListingsItem">
        <v>0</v>
        <id>test/1080i25spts3NascarSchool3mints_feature</id>
        <t>feature</t>
        <n>Nascar_Racing_School_feature</n>
        <fl>
            <f>HD</f>
        </fl>
        <al>
            <a k="AssetId">
                <v>1080i25spts3NascarSchool3mints_feature</v>
            </a>
            <a k="StreamFormat">
                <v>rtp</v>
            </a>
            <a k="RuntimeSeconds">
                <v>175</v>
            </a>
            <a k="DefaultLanguage">
                <v>en</v>
            </a>
            <a k="Content">
                <v t="FileName">1080i25-spts-3-NascarSchool-3min.ts</v>
                <v t="SizeInBytes" />
                <v t="NetworkType" />
                <v t="KBPS" />
                <v t="PlayReady" />
                <v t="WebInitiatorUrl" />
                <v t="LicenseServerProxyUrl" />
                <v t="Type" />
                <v t="PitchedFilename">1080i25-spts-3-NascarSchool-3min.ts</v>
            </a>
            <a k="ProcessContent">
                <v t="SourceFilePath">1080i25-spts-3-NascarSchool-3min.ts</v>
                <v t="DestinationDirectory">Media/e9959908-dabc-4691-a190-a30668d5c797</v>
                <v t="HD">true</v>
                <v t="HDCPDisable">false</v>
                <v t="Status">true</v>
                <v t="ServiceInformationID">e9959908-dabc-4691-a190-a30668d5c797</v>
                <v t="AssetType">feature</v>
                <v t="StreamFormat">rtp</v>
            </a>
        </al>
        <sol />
        <rl>
            <r>MPAA,R</r>
        </rl>
    </so>
    <so type="ListingsItem">
        <v>0</v>
        <id>test/1080i25spts3NascarSchool3mintsposter</id>
        <t>poster</t>
        <n>Nascar_Racing_School_poster</n>
        <fl>
            <f>SD</f>
        </fl>
        <al>
            <a k="AssetId">
                <v>1080i25spts3NascarSchool3mintsposter</v>
            </a>
            <a k="DefaultLanguage">
                <v>en</v>
            </a>
            <a k="Content">
                <v t="FileName">nascarschool_new.jpg</v>
                <v t="SizeInBytes" />
                <v t="NetworkType" />
                <v t="KBPS" />
                <v t="PlayReady" />
                <v t="WebInitiatorUrl" />
                <v t="LicenseServerProxyUrl" />
                <v t="Type" />
                <v t="PitchedFilename">nascarschool_new.jpg</v>
            </a>
            <a k="OrigFileLoc">
                <v>147\106\test-HD30002\Poster\nascarschool_new.jpg</v>
            </a>
            <a k="PosterUrl">
                <v>/posters/147/106/test-HD30002/Poster/nascarschool_new__{0}.jpg</v>
            </a>
        </al>
        <sol />
        <rl>
            <r>MPAA,R</r>
        </rl>
    </so>
</sol>'
    );

    SELECT CONVERT(datetime, 
               CONVERT(nvarchar(1000), 
                   (CONVERT(xml, [ColumnName])).query('(sol/so/al/a[@k=''LicensingWindowStart''])/v/text()')
               )
           ) AS LicensingWindowStart
    FROM TextXmlTable;

似乎您最大的问题是出于某种原因尝试在查询中包含“SOL”节点......