Sql server 使用XML名称空间打开XML选择值

Sql server 使用XML名称空间打开XML选择值,sql-server,xml,tsql,xpath,xquery,Sql Server,Xml,Tsql,Xpath,Xquery,我试图在SQLServer2012中使用OpenXML选择一些值。当我没有任何xml名称空间时,这就起作用了。但每当下面的前缀与根元素一起添加时,我就无法选择值。关于如何使用xmlns选择值的任何建议: xmlns=“somenamspace/2006-10-31”订单号=“00000001” 使用grails 去 将@XML声明为XML,@hDoc声明为INT,@SQL NVARCHAR(MAX),@rootxmlns varchar(100) 选择@XML=N' 2017-07-24T20:

我试图在SQLServer2012中使用OpenXML选择一些值。当我没有任何xml名称空间时,这就起作用了。但每当下面的前缀与根元素一起添加时,我就无法选择值。关于如何使用xmlns选择值的任何建议:

xmlns=“somenamspace/2006-10-31”订单号=“00000001”

使用grails
去
将@XML声明为XML,@hDoc声明为INT,@SQL NVARCHAR(MAX),@rootxmlns varchar(100)
选择@XML=N'
2017-07-24T20:48:57.000Z
00000001
abcd abcd
jjj@gmail.com
00000001
签证
XXXX-XXXX-XXXX-1111
abcd
1.
2021
325.48
';
设置@rootxmlns=''
EXEC sp_xml_preparedocument@hDoc OUTPUT,@xml,@rootxmlns
选择订单号
来自OPENXML(@hDoc,'ns1:order',2)
具有
(
订单号[varchar](50)“原始订单号”
)
挑选*
来自OPENXML(@hDoc,'ns1:order/customer',2)
具有
(
客户名称[varchar](50)“客户名称”,
customerEmail[varchar](100)“客户电子邮件”
)
选择卡类型、卡号、持卡人
来自OPENXML(@hDoc,'/order/payments/payment/credit-card',2)
具有
(
cardType[varchar](50)“卡类型”,
卡号[varchar](100)“卡号”,
持卡人[varchar](100)“持卡人”
)
EXEC sp_xml_removedocument@hDoc
去

明白了,还需要在属性级别添加名称空间:

SET @rootxmlns = '<root xmlns:ns1="http://www.demandware.com/xml/impex/order/2006-10-31"/>'
EXEC sp_xml_preparedocument @hDoc OUTPUT, @XML, @rootxmlns


SELECT orderNo
FROM OPENXML(@hDoc, 'ns1:order',2)
WITH 
(
orderNo [varchar](50) 'ns1:original-order-no'
)


SELECT *
FROM OPENXML(@hDoc, 'ns1:order/ns1:customer',2)
WITH 
(
customerName [varchar](50) 'ns1:customer-name',
customerEmail [varchar](100) 'ns1:customer-email'
)


SELECT cardType, cardNumber, cardHolder
FROM OPENXML(@hDoc, 'ns1:order/ns1:payments/ns1:payment/ns1:credit-card',2)
WITH 
(
cardType [varchar](50) 'ns1:card-type',
cardNumber [varchar](100) 'ns1:card-number',
cardHolder [varchar](100) 'ns1:card-holder'
)

EXEC sp_xml_removedocument @hDoc
GO
SET@rootxmlns=''
EXEC sp_xml_preparedocument@hDoc OUTPUT,@xml,@rootxmlns
选择订单号
来自OPENXML(@hDoc,'ns1:order',2)
具有
(
订单号[varchar](50)'ns1:原始订单号'
)
挑选*
来自OPENXML(@hDoc,'ns1:order/ns1:customer',2)
具有
(
客户名称[varchar](50)“ns1:客户名称”,
customerEmail[varchar](100)“ns1:客户电子邮件”
)
选择卡类型、卡号、持卡人
来自OPENXML(@hDoc,'ns1:order/ns1:payments/ns1:payment/ns1:credit-card',2)
具有
(
cardType[varchar](50)“ns1:卡类型”,
卡号[varchar](100)“ns1:卡号”,
持卡人[varchar](100)“ns1:持卡人”
)
EXEC sp_xml_removedocument@hDoc
去

很好,你自己已经找到了答案,但是这个问题可以解决得更好

使用相应的SP打开和删除文档的OPENXML中的
已过时,不应再使用。本机XML类型提供了以下功能,而不是使用这些方法:

以下内容将至少为您提供一些模板,用于访问XML中的值:

DECLARE @XML AS XML=
N'<order xmlns="somenamspace/2006-10-31" order-no="00000001">
  <order-date>2017-07-24T20:48:57.000Z</order-date>
  <original-order-no>00000001</original-order-no>
  <customer>
    <customer-name>abcd abcd</customer-name>
    <customer-email>jjj@gmail.com</customer-email>
  </customer>
  <current-order-no>00000001</current-order-no>
  <payments>
    <payment>
      <credit-card>
        <card-type>VISA</card-type>
        <card-number>XXXX-XXXX-XXXX-1111</card-number>
        <card-holder>abcd</card-holder>
        <expiration-month>1</expiration-month>
        <expiration-year>2021</expiration-year>
      </credit-card>
      <amount>325.48</amount>
    </payment>
  </payments>
</order>';
结果

Nr OrderDate                CustomerName    PaymentType   CardType  Amount
1  2017-07-24 20:48:57.000  abcd abcd       credit-card   VISA      325.4800
解释
一些数据是通过
XPath
直接从
@xml
中获取的。@xml.nodes()中的语句
将创建
节点的派生表(正如措辞所暗示的
1:n
关系。
节点被明确处理,
中的另一个节点被视为支付详细信息。

非常感谢您展示了正确的方式。如果我有多张信用卡,我还有一个问题,我如何循环它们,而不是直接传递number-@xml.value(N'(/order/@order no)[1],,N'int')@PinakiMukherjee请用一些实际(但简化)的XML示例开始一个新问题,并说明预期的输出。新问题最吸引人。我(或其他人)很快就会来……谢谢Shungo。我将打开一个新问题。
WITH XMLNAMESPACES(DEFAULT N'somenamspace/2006-10-31')
SELECT @xml.value(N'(/order/@order-no)[1]',N'int') AS OrderNumber
      ,@xml.value(N'(/order/order-date/text())[1]',N'datetime') AS OrderDate
      ,@xml.value(N'(/order/customer/customer-name/text())[1]',N'nvarchar(max)') AS CustomerName
      ,p.value(N'local-name(.)',N'nvarchar(max)') AS PaymentType
      ,p.value(N'(card-type/text())[1]','nvarchar(max)') AS CardType
      ,p.value(N'(../amount/text())[1]','decimal(10,4)') AS Amount
FROM @xml.nodes(N'/order/payments/payment/*[local-name()!="amount"]') AS A(p)
Nr OrderDate                CustomerName    PaymentType   CardType  Amount
1  2017-07-24 20:48:57.000  abcd abcd       credit-card   VISA      325.4800