简体   繁体   中英

SQL Query values out of XML using

I can't figure out what I'm doing wrong. I have XML stored in a table column as text. I'm taking the ID, and the XML text and querying it into a temp table that stores the XML as XML type.

Each Order in the XML has multiple licenses in it that I need to pull out and create a new table with OrderID and License ID. But I can't tell what I'm doing wrong.

So, I'm trying to start basic but I can't seem to even just get the Account Info from the first Node.

The XML looks like this:

 <ns1:OrderFromCRM xmlns:ns1="http://company.com/licensing/neworder/v2">
      <ns1:AccountInfo Name="Company Name" AccountId="A012345" />
      <ns1:OrderInfo CRMOrderId="S147360" Date="2/23/2017 12:00:00 AM" ffEmail="emailaddress.@gmail.com" >
        <ns1:Licensing>
          <ns1:Foundations>
            <ns1:Foundation LicenseId="L012345678" Action="Create" Environment="Production" Type="Enterprise">
              <Metadata>
                <AllowedInstances>999</AllowedInstances>
              </Metadata>
            </ns1:Foundation>
            <ns1:Foundation LicenseId="L012345698" Action="Create" Environment="Production" Type="Enterprise">
              <Metadata>
                <AllowedInstances>999</AllowedInstances>
              </Metadata>
            </ns1:Foundation>
          </ns1:Foundations>
          <ns1:Licenses Type="Create">
            <ns1:License LicenseId="L0123451234" ProductFamily="Fam1" Product="EStudio" LicenseType="Perpetual" StartDate="2017-02-23" ExpiryDate="2017-12-18" MaintenanceExpiryDate="2017-12-18">
              <ns1:Capabilities>
                <ns1:Capability Name="T1" />
                <ns1:Capability Name="Q1" />
                <ns1:Capability Name="B1" />
              </ns1:Capabilities>
            </ns1:License>
            <ns1:License LicenseId="L333356675"  ProductFamily="Fam1" Product="EStudio" LicenseType="Perpetual" StartDate="2017-02-23" ExpiryDate="2017-12-18" MaintenanceExpiryDate="2017-12-18">
              <ns1:Capabilities>
                <ns1:Capability Name="T1" />
                <ns1:Capability Name="Q1" />
                <ns1:Capability Name="B1" />
              </ns1:Capabilities>
            </ns1:License>

The SQL I wrote is:

CREATE TABLE #demoData
 (
    ActivationCode NVARCHAR(100) NOT NULL,
    OrderXMLText XML
 )

SELECT OrderId, OrderXMLText.value('(/OrderFromCRM/AccountInfo)[1]', 'varchar(30)') 
FROM #DEMODATA

I mentioned I need the OrderID and the LicenseId but even with this, I can't get anything. Am I on right track? First, what am I missing? Second, once this is formatted correctly, how do I get the nested LicenseIds in the XML?

Thanks so much for any help. I've been trying to make this work for a couple days

You're missing the namespace so the query isn't matching the xml, therefore it doesn't find the elements you're querying.

Add

;WITH XMLNAMESPACES

https://docs.microsoft.com/en-us/sql/t-sql/xml/with-xmlnamespaces

Assuming you have a complete, valid XML document in your table (the one you're showing is lacking several closing tags), then you could try something like this:

;WITH XMLNAMESPACES('http://company.com/licensing/neworder/v2' AS ns1)
SELECT
    ActivationCode, 
    CRMOrderId = XC.value('@CRMOrderId', 'varchar(100)'),
    FoundationsLicenseId = xcf.value('@LicenseId', 'varchar(50)'),
    LicensesLicenseId = xcl.value('@LicenseId', 'varchar(50)')
FROM
    #demoData
CROSS APPLY
    OrderXMLText.nodes('/ns1:OrderFromCRM/ns1:OrderInfo') AS XT(XC)
CROSS APPLY
    XC.nodes('ns1:Licensing/ns1:Foundations/ns1:Foundation') AS XTF(XCF)
CROSS APPLY
    XC.nodes('ns1:Licensing/ns1:Licenses/ns1:License') AS XTL(XCL)

First of all, you need to include and respect the XML namespace in your XQuery - that's what I do with the WITH XMLNAMESPACES() directive.

Next, you need to use .nodes() to get a list of XML fragments for each <OrderInfo> node, which is located below the root node ( <OrderFromCRM> ). This is the first CROSS APPLY . This returns a list of XML fragments, one for each <OrderInfo> node.

Then you need to reach into these XML fragments, and again use CROSS APPLY with the .nodes() function to get a list of the <Foundation> elements (contained in the <Licensing>/<Foundations> subtree to get the license Id's from those nodes. In addition, you need a second CROSS APPLY to get all the <License> subnodes under <Licensing>/<Licenses> to get those LicenseId attributes.

That should return an output something like:

在此处输入图片说明

Hope this helps you some!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM