如何从SQL中的XML获取值

时间:2019-05-23 12:51:26

标签: sql xml

我找不到错误。选择s为空,但不可以...

declare @xml xml =
'<ArrayOfFinancialDecimalKeyValue xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Quipu.CRMExtensions.BusinessLogicLayer.Financials.Models.Financials">
  <FinancialDecimalKeyValue>
    <ReferenceCode>fx_risk_lt_st_liabilities_currency3_realistic_percentage_input</ReferenceCode>
    <Value>5</Value>
    <AttributeName>fx_risk_lt_st_liabilities_currency3_realistic_percentage</AttributeName>
    <Type1>realistic_percentage</Type1>
    <Type2>currency3</Type2>
    <IsDivByZero i:nil="true" />
  </FinancialDecimalKeyValue>
  <FinancialDecimalKeyValue>
    <ReferenceCode>fx_risk_lt_st_liabilities_currency3_realistic2ndYear_percentage_input</ReferenceCode>
    <Value>5</Value>
    <AttributeName>fx_risk_lt_st_liabilities_currency3_realistic2ndYear_percentage</AttributeName>
    <Type1>realistic2ndYear_percentage</Type1>
    <Type2>currency3</Type2>
    <IsDivByZero i:nil="true" />
  </FinancialDecimalKeyValue>
</ArrayOfFinancialDecimalKeyValue>'

SELECT  

       _xml.col.value('(ReferenceCode)[1]','varchar(150)') as [ReferenceCode],
       _xml.col.value('(Value)[1]','varchar(50)') as [Value],
       _xml.col.value('(AttributeName)[1]','varchar(50)') as [BalanceSheetExchangeRate],
       _xml.col.value('(Type1)[1]','varchar(50)') as [Type1]  ,
       _xml.col.value('(Type2)[1]','varchar(50)') as [Type2],
       _xml.col.value('(IsDivByZero)[1]','varchar(50)') as [IsDivByZero]            


FROM   @xml.nodes('//FinancialDecimalKeyValue') as _xml(col)

1 个答案:

答案 0 :(得分:0)

您的查询正在使用默认名称空间。有几种处理方法,但最简单的方法是to use WITH XMLNAMESPACES

dispatch

这将返回

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Quipu.CRMExtensions.BusinessLogicLayer.Financials.Models.Financials')
SELECT  

       _xml.col.value('(ReferenceCode)[1]','varchar(150)') as [ReferenceCode],
       _xml.col.value('(Value)[1]','varchar(50)') as [Value],
       _xml.col.value('(AttributeName)[1]','varchar(50)') as [BalanceSheetExchangeRate],
       _xml.col.value('(Type1)[1]','varchar(50)') as [Type1]  ,
       _xml.col.value('(Type2)[1]','varchar(50)') as [Type2],
       _xml.col.value('(IsDivByZero)[1]','varchar(50)') as [IsDivByZero]            
FROM   @xml.nodes('//FinancialDecimalKeyValue') as _xml(col);

更新

您的评论对我来说并不十分清楚...我知道,您尝试像使用CTE一样使用+-----------------------------------------------------------------------+-------+----------------------------------------------------+-----------------------------+-----------+-------------+ | ReferenceCode | Value | BalanceSheetExchangeRate | Type1 | Type2 | IsDivByZero | +-----------------------------------------------------------------------+-------+----------------------------------------------------+-----------------------------+-----------+-------------+ | fx_risk_lt_st_liabilities_currency3_realistic_percentage_input | 5 | fx_risk_lt_st_liabilities_currency3_realistic_perc | realistic_percentage | currency3 | | +-----------------------------------------------------------------------+-------+----------------------------------------------------+-----------------------------+-----------+-------------+ | fx_risk_lt_st_liabilities_currency3_realistic2ndYear_percentage_input | 5 | fx_risk_lt_st_liabilities_currency3_realistic2ndYe | realistic2ndYear_percentage | currency3 | | +-----------------------------------------------------------------------+-------+----------------------------------------------------+-----------------------------+-----------+-------------+ 。好吧,如果您需要CTE,则可以执行以下操作:

XMLNAMESPACES

但是我想,这就是您要寻找的东西:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Quipu.CRMExtensions.BusinessLogicLayer.Financials.Models.Financials')
,CTE AS
(
    SELECT  

           _xml.col.value('(ReferenceCode)[1]','varchar(150)') as [ReferenceCode],
           _xml.col.value('(Value)[1]','varchar(50)') as [Value],
           _xml.col.value('(AttributeName)[1]','varchar(50)') as [BalanceSheetExchangeRate],
           _xml.col.value('(Type1)[1]','varchar(50)') as [Type1]  ,
           _xml.col.value('(Type2)[1]','varchar(50)') as [Type2],
           _xml.col.value('(IsDivByZero)[1]','varchar(50)') as [IsDivByZero]            
    FROM   @xml.nodes('//FinancialDecimalKeyValue') as _xml(col)
)
SELECT * FROM CTE;

这将仅返回值“ 5”。

更好的表现是这样:

;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Quipu.CRMExtensions.BusinessLogicLayer.Financials.Models.Financials')
SELECT _xml.col.value('(Value)[1]','varchar(50)') as [Value]
FROM   @xml.nodes('//FinancialDecimalKeyValue') as _xml(col)
WHERE _xml.col.value('(Type1)[1]','varchar(50)')='realistic_percentage' 
  AND _xml.col.value('(ReferenceCode)[1]','varchar(150)')='fx_risk_lt_st_liabilities_currency3_realistic_percentage_input' 

最后一个读为:潜入DECLARE @code VARCHAR(100)='fx_risk_lt_st_liabilities_currency3_realistic_percentage_input'; DECLARE @type1 VARCHAR(100)='realistic_percentage'; ;WITH XMLNAMESPACES(DEFAULT 'http://schemas.datacontract.org/2004/07/Quipu.CRMExtensions.BusinessLogicLayer.Financials.Models.Financials') SELECT @xml.value('(/ArrayOfFinancialDecimalKeyValue /FinancialDecimalKeyValue[(ReferenceCode/text())[1]=sql:variable("@code") and (Type1/text())[1]=sql:variable("@type1")] /Value/text())[1]','varchar(50)') as [Value]; 。然后查找元素<ArrayOfFinancialDecimalKeyValue>,该元素将填充 XQuery谓词,并返回其<FinancialDecimalKeyValue>

更新2

也许是,您只是误解了<Value>的语法?

尝试一下

INSERT INTO