Tsql 将SOAP XML完全导入SQL Server 2012
我有一个SOAP响应,需要将soapenv:Body的几乎所有字段导入SQL Server 通过谷歌搜索和测试,我构建了这个似乎有效的查询 但这并不是我想要的:Tsql 将SOAP XML完全导入SQL Server 2012,tsql,soap,sql-server-2012,xquery,Tsql,Soap,Sql Server 2012,Xquery,我有一个SOAP响应,需要将soapenv:Body的几乎所有字段导入SQL Server 通过谷歌搜索和测试,我构建了这个似乎有效的查询 但这并不是我想要的: declare @Root varchar(50)='/soap:Envelope/soap:Body/GetFeedbackResponse/', @xDoc XML = '<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv
declare
@Root varchar(50)='/soap:Envelope/soap:Body/GetFeedbackResponse/',
@xDoc XML = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ebl:RequesterCredentials soapenv:mustUnderstand="0" xmlns:ns="urn:ebay:apis:eBLBaseComponents" xmlns:ebl="urn:ebay:apis:eBLBaseComponents">
<ebl:NotificationSignature xmlns:ebl="urn:ebay:apis:eBLBaseComponents">r6revSiTXCP9SBBFUtpDAQ==</ebl:NotificationSignature>
</ebl:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<GetFeedbackResponse xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2015-09-06T11:20:48.528Z</Timestamp>
<Ack>Success</Ack>
<CorrelationID>428163922470</CorrelationID>
<Version>899</Version>
<Build>E899_INTL_APIFEEDBACK_17278558_R1</Build>
<NotificationEventName>Feedback</NotificationEventName>
<RecipientUserID>ebay_bestseller</RecipientUserID>
<EIASToken>nY+sHZ2PrBmdj6wVnY+sEWDETj2dj6AFlIajDpaEpAydj6x9nY+seQ==</EIASToken>
<FeedbackDetailArray>
<FeedbackDetail>
<CommentingUser>ebay_bestseller</CommentingUser>
<CommentingUserScore>42425</CommentingUserScore>
<CommentText>Great buyer - We Would Appreciate 5 STARS for Our Feedback!</CommentText>
<CommentTime>2015-09-06T11:20:45.000Z</CommentTime>
<CommentType>Positive</CommentType>
<ItemID>310541589307</ItemID>
<Role>Buyer</Role>
<FeedbackID>1064451206013</FeedbackID>
<TransactionID>549674542021</TransactionID>
<OrderLineItemID>310541589307-549674542021</OrderLineItemID>
</FeedbackDetail>
</FeedbackDetailArray>
<FeedbackDetailItemTotal>1</FeedbackDetailItemTotal>
<FeedbackScore>126</FeedbackScore>
<PaginationResult>
<TotalNumberOfPages>1</TotalNumberOfPages>
<TotalNumberOfEntries>1</TotalNumberOfEntries>
</PaginationResult>
<EntriesPerPage>25</EntriesPerPage>
<PageNumber>1</PageNumber>
</GetFeedbackResponse>
</soapenv:Body>
</soapenv:Envelope>'
;with xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as [soap], default 'urn:ebay:apis:eBLBaseComponents')
insert into Test (TS,Comment)
select
@xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/Timestamp)[1]', 'nvarchar(max)'),
@xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/FeedbackDetailArray/FeedbackDetail/CommentText)[1]', 'nvarchar(max)'),
........
而不是
@xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/Timestamp)[1]', 'nvarchar(max)')
但我收到一个错误,比如第一个值必须是文本值:有什么转机吗
第三:从文档中…需要查询
@xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/Timestamp)[1]', 'nvarchar(max)')
返回一个值,否则将引发错误
但在某些肥皂中,某些字段是可选字段,因此并不总是存在:
我试过了
;with xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as [soap], default 'urn:ebay:apis:eBLBaseComponents')
insert into Test (TS,Comment)
select if (exists @xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/Timestamp)')) then @xDoc.value('(/soap:Envelope/soap:Body/GetFeedbackResponse/Timestamp)[1]', 'nvarchar(max)')
....
但是提出一个错误:哪一个是正确的查询表单
非常感谢
Joe另一种方法是获取一个名称值结果集而不是列,然后您可以按照自己的意愿处理它。如果希望结果作为列,例如,可以将名称值结果集存储在临时表中,并对数据进行动态透视
declare
@Root varchar(50)='GetFeedbackResponse',
@xDoc XML = '<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<ebl:RequesterCredentials soapenv:mustUnderstand="0" xmlns:ns="urn:ebay:apis:eBLBaseComponents" xmlns:ebl="urn:ebay:apis:eBLBaseComponents">
<ebl:NotificationSignature xmlns:ebl="urn:ebay:apis:eBLBaseComponents">r6revSiTXCP9SBBFUtpDAQ==</ebl:NotificationSignature>
</ebl:RequesterCredentials>
</soapenv:Header>
<soapenv:Body>
<GetFeedbackResponse xmlns="urn:ebay:apis:eBLBaseComponents">
<Timestamp>2015-09-06T11:20:48.528Z</Timestamp>
<Ack>Success</Ack>
<CorrelationID>428163922470</CorrelationID>
<Version>899</Version>
<Build>E899_INTL_APIFEEDBACK_17278558_R1</Build>
<NotificationEventName>Feedback</NotificationEventName>
<RecipientUserID>ebay_bestseller</RecipientUserID>
<EIASToken>nY+sHZ2PrBmdj6wVnY+sEWDETj2dj6AFlIajDpaEpAydj6x9nY+seQ==</EIASToken>
<FeedbackDetailArray>
<FeedbackDetail>
<CommentingUser>ebay_bestseller</CommentingUser>
<CommentingUserScore>42425</CommentingUserScore>
<CommentText>Great buyer - We Would Appreciate 5 STARS for Our Feedback!</CommentText>
<CommentTime>2015-09-06T11:20:45.000Z</CommentTime>
<CommentType>Positive</CommentType>
<ItemID>310541589307</ItemID>
<Role>Buyer</Role>
<FeedbackID>1064451206013</FeedbackID>
<TransactionID>549674542021</TransactionID>
<OrderLineItemID>310541589307-549674542021</OrderLineItemID>
</FeedbackDetail>
</FeedbackDetailArray>
<FeedbackDetailItemTotal>1</FeedbackDetailItemTotal>
<FeedbackScore>126</FeedbackScore>
<PaginationResult>
<TotalNumberOfPages>1</TotalNumberOfPages>
<TotalNumberOfEntries>1</TotalNumberOfEntries>
</PaginationResult>
<EntriesPerPage>25</EntriesPerPage>
<PageNumber>1</PageNumber>
</GetFeedbackResponse>
</soapenv:Body>
</soapenv:Envelope>'
select T.X.value('local-name(.)', 'nvarchar(100)') as Name,
T.X.value('text()[1]', 'nvarchar(100)') as Value
from @xDoc.nodes('//*[local-name(.) = sql:variable("@Root")]//*') as T(X)
第三名:
你应该再读一遍
XQuery最多只能返回一个值
不返回任何值是完全可以的,在这种情况下,返回的值是NULL
更新:
如果您要查找的最终结果实际上是一行,列中有值,那么最好使用您已经计算出的结果。通过将所有值的公共路径放在nodes()
子句中,可以稍微简化它。像这样的
with xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as [soap], default 'urn:ebay:apis:eBLBaseComponents')
select T.X.value('(Timestamp/text())[1]', 'datetime') as Timestamp,
T.X.value('(Ack/text())[1]', 'varchar(10)') as Ack,
T.X.value('(CorrelationID/text())[1]', 'varchar(20)') as CorrelationID
from @xDoc.nodes('/soap:Envelope/soap:Body/GetFeedbackResponse') as T(X)
只需添加实际需要的额外列。我还将
/text()
添加到从节点提取值的位置。对于XML,它将给出与您已有的结果完全相同的结果,只有优化器可以从查询计划中排除几个运算符,因此这样分解可能会更快。OK此解决方案比我的解决方案简单得多,并且可以获得几乎所有的数据。。但这太复杂了,用我目前的知识我无法理解,我不知道如何进一步,所以我想寻求进一步的帮助。深入:对于这个SOAP,最重要的字段都在FeedbackDetail中,而我有一个空值:如何获取那个细节?使用你建议的动态枢轴?你能给我一些进一步的提示吗?那么如何避免一些领域?比WHERE T.X.value('local-name(.),'nvarchar(100)'Version'
或NOT IN('',)
更简单的东西最后如何构建动态更新查询?您认为主要问题的一个解决方案是集成xQuery函数叶元素吗?这是正确的方向吗?@Joe你最好的选择可能是继续你已经走的路。我添加了一种构建查询的方法,该方法与您现有的方法稍有不同,并且可能在形式上更简单。好吧,你的解决方案要好得多,如果我的技能允许的话,我愿意朝这个方向前进:我有大约50种不同的肥皂剧,你的解决方案允许我只写一个例程,而不是为每个肥皂剧写一个。。但如果节点有子节点,则需要获取最后一个子节点的text():必须有一种方法来实现这一点。。只要找到它就行了还在这里。。我添加了[count(child::*)=0]
ad-end-of-from以避免空行。。我想我几乎拥有了我所需要的。。现在,我们将构建更新查询。。谢谢!
Name Value
------------------------- -----------------------------------------------
Timestamp 2015-09-06T11:20:48.528Z
Ack Success
CorrelationID 428163922470
Version 899
Build E899_INTL_APIFEEDBACK_17278558_R1
NotificationEventName Feedback
RecipientUserID ebay_bestseller
EIASToken nY+sHZ2PrBmdj6wVnY+sEWDETj2dj6AFlIajDpaEpAydj6x9nY+seQ==
FeedbackDetailArray NULL
FeedbackDetail NULL
CommentingUser ebay_bestseller
CommentingUserScore 42425
CommentText Great buyer - We Would Appreciate 5 STARS for Our Feedback!
CommentTime 2015-09-06T11:20:45.000Z
CommentType Positive
ItemID 310541589307
Role Buyer
FeedbackID 1064451206013
TransactionID 549674542021
OrderLineItemID 310541589307-549674542021
FeedbackDetailItemTotal 1
FeedbackScore 126
PaginationResult NULL
TotalNumberOfPages 1
TotalNumberOfEntries 1
EntriesPerPage 25
PageNumber 1
with xmlnamespaces('http://schemas.xmlsoap.org/soap/envelope/' as [soap], default 'urn:ebay:apis:eBLBaseComponents')
select T.X.value('(Timestamp/text())[1]', 'datetime') as Timestamp,
T.X.value('(Ack/text())[1]', 'varchar(10)') as Ack,
T.X.value('(CorrelationID/text())[1]', 'varchar(20)') as CorrelationID
from @xDoc.nodes('/soap:Envelope/soap:Body/GetFeedbackResponse') as T(X)