【问题标题】:Querying XML within SQL Server with namespace在 SQL Server 中使用命名空间查询 XML
【发布时间】:2015-02-04 21:12:10
【问题描述】:

我正在尝试查询我发送的一些 XML 数据。我遵循了各种示例,但甚至无法解决根目录下的任何元素。我不确定我错过了什么。我试过简单地将 xml 拉到 /KitchenSupply/StoreInfo 下面,什么也没有。命名空间是我无法返回任何东西的罪魁祸首吗?

declare @myxmlinv as xml = 
'<?xml version="1.0" encoding="utf-8"?>
<KitchenSupply xmlns="http://www.starstandards.org/STAR" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="KitchenSupply.xsd">
  <StoreInfo>
    <RCPT>
      <SubTaskCode>ZZZ</SubTaskCode>
      <SubComponentCode>BS1</SubComponentCode>
      <StoreNumber>2241</StoreNumber>
      <USRegionNumber>SE</USRegionNumber>
    </RCPT>
    <SentDateTime>02/04/2015</SentDateTime>
    <IntId>ABC1234587</IntId>
    <Destinations>
      <DestinationFormatType>KS_XML_v3</DestinationFormatType>
    </Destinations>
  </StoreInfo>
  <KitchenOrder>
    <KsRecord SalesTransactionPayType="CC" SalesTransactionType="Closed">
      <ReceiptAmt RcptTotalAmt="0.00" CustRcptTotalAmt="25.22" CCPostDate="01/07/2015" InvoiceDate="01/05/2015" CustName="JOHN SMITH" CustNo="13998" RcptNo="78476221" />
      <KsCosts>
        <SaleAmts UnitCost="15.00" TxblAmt="15.00" PayType="Cust" />
        <SalesInfo JobStatus="F" JobNo="1" ItemCode="HT093" ItemDesc="Hand Towel">
          <EmpInfo EmpRate="16.00" EmpCommPct="1.2" EmpName="DOUG ROGERS" EmpNo="998331" />
        </SalesInfo>
      </KsCosts>
    </KsRecord>
    <CustomerRecord>
      <ContactInfo LastName="SMITH" FreqFlag="Y">
        <Address Zip="90210" State="CA" City="BEV" Addr1="123 MAIN ST" Type="Business" />
        <Email MailTo="FAKE@USA.COM" />
        <Phone Num="1235551212" Type="H" />
        <Phone Num="1235551213" Type="B" />
      </ContactInfo>
    </CustomerRecord>
  </KitchenOrder>
  <KitchenOrder>
    <KsRecord SalesTransactionPayType="CC" SalesTransactionType="Closed">
      <ReceiptAmt RcptTotalAmt="0.00" CustRcptTotalAmt="5.71" CCPostDate="01/08/2015" InvoiceDate="01/07/2015" CustName="SARAH BALDWIN" CustNo="14421" RcptNo="78476242" />
      <KsCosts>
        <SaleAmts UnitCost="2.00" TxblAmt="2.00" PayType="Cust" />
        <SalesInfo JobStatus="F" JobNo="1" ItemCode="HS044" ItemDesc="Hand Soap">
          <EmpInfo EmpRate="16.00" EmpCommPct="1.2" EmpName="DOUG ROGERS" EmpNo="998331" />
        </SalesInfo>
      </KsCosts>
    </KsRecord>
    <CustomerRecord>
      <ContactInfo LastName="BALDWIN" FreqFlag="N">
        <Address Zip="90210" State="CA" City="BEV" Addr1="123 VINE ST" Type="Home" />
        <Email MailTo="FAKESARAH@USA.COM" />
        <Phone Num="1235555512" Type="H" />
        <Phone Num="1235556613" Type="M" />
      </ContactInfo>
    </CustomerRecord>
  </KitchenOrder>
</KitchenSupply>';


declare @myxmlinv_table as table (
 row_id tinyint,
 inv_xml xml   
);

insert into @myxmlinv_table(row_id,inv_xml) values('1',@myxmlinv);

显示 XML 文档并拉取 IntId 列:(不起作用)

select i.row_id, i.inv_xml, i.inv_xml.value('(/KitchenSupply/StoreInfo/IntId)[1]','varchar(255)') as data_description
from @myxmlinv_table i

尝试使用 XMLNAMESPACES 在 StoreInfo 级别显示 XML 文档:(也不起作用)

WITH XMLNAMESPACES ('http://www.starstandards.org/STAR' as ks)
SELECT 
   XmlCol.query('/ks:KitchenSupply/StoreInfo')
FROM T;

理想情况下,我想使用节点来提取和提取所有数据到单独的表中进行查询。

KitchenOrders 都在一个表中,CustomerRecord 在另一个表中,等等。

有什么想法吗?

【问题讨论】:

    标签: sql-server xml sql-server-2008 xquery-sql


    【解决方案1】:

    你需要使用这样的东西:

    -- define the XML namespace as the "default" so you don't have to 
    -- prefix each and every XPath element with the XML namespace prefix
    WITH XMLNAMESPACES( DEFAULT 'http://www.starstandards.org/STAR')
    SELECT
        -- reach into the <KsRecord> subnode under <KitchenOrder>
        ReceiptNo = XC.value('(KsRecord/ReceiptAmt/@RcptNo)[1]', 'int'),
        CustName = XC.value('(KsRecord/ReceiptAmt/@CustName)[1]', 'varchar(25)'),
        -- reach into the <CustomerRecord> subnode under <KitchenOrder>     
        CustomerLastName = xc.value('(CustomerRecord/ContactInfo/@LastName)[1]', 'varchar(50)'),
        CustomerEmail = xc.value('(CustomerRecord/ContactInfo/Email/@MailTo)[1]', 'varchar(50)')
    FROM
        -- get a "virtual" table of XML fragments, one for each <KitchenOrder> node
        @myxmlinv.nodes('/KitchenSupply/KitchenOrder') AS XT(XC)
    

    【讨论】:

    • 外观和效果都很棒!谢谢,希望我能对此进行扩展。
    【解决方案2】:

    是的,它是命名空间。要让 SQL Server 忽略命名空间,您可以使用 local-name:

    SELECT *
    FROM @myxmlinv_table
    WHERE inv_xml.exist('//*[local-name()="KitchenSupply"]') = 1
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多