如何在 sql 查询中解析多个命名空间 xml
How to parse multiple namespaces xml in sql query
我有一个 table,其中包含一个 XML 列,我正在尝试从 XML 数据中获取某些列。这些列位于 PositionRoles
标记下,该标记是 has INSERT
语句的一部分。不幸的是,我得到了 NULL
个值。
这是我使用的 XML 示例:
<request-broker-message version="1.0">
<request class="UPDATE_ORGANISATION_HIERARCHY" culture="tr-TR">
<parameter name="OrgHierarchyDatasets_schema">
(here is not important...)
</parameter>
<parameter name="OrgHierarchyDatasets_diffgram">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<POSTN_ID>0000-0000H1-POS</POSTN_ID>
<ROLE_ID>0000-00002B-ROL</ROLE_ID>
<STATUS>1</STATUS>
</PositionRoles>
</NewDataSet>
</diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>
</request>
</request-broker-message>
我的尝试:
;WITH XMLNAMESPACES('urn:schemas-microsoft-com:xml-diffgram-v1' AS diffgr,
'inserted' AS hasChanges)
INSERT INTO TMP_ORGANIZATION_HIERARCHY_LOGS_TABLE(POSITION_ID, OPERATION, ROLE_ID, PACKET_OWNER, RESPONSE_TIME)
SELECT
*
FROM TMP_PACKET_LOG_TABLE (NOLOCK)
WHERE
RESPONSE_PACKET.value('(/request-broker-message/request/parameter[@name="OrgHierarchyDatasets_diffgram"]//NewDataSet/hasChanges:PositionRoles/hasChanges:STATUS)[1]', 'varchar(1)') = '1'
不确定您所追求的具体价值是什么,但这应该足以让您到达那里。您需要在 WITH
中放置适当的名称空间( 不 以 ;
开头,语句以 1 结尾),然后在相关前缀具有相关命名空间名称的节点(例如 diffgr:
对应 diffgram
):
DECLARE @XML xml =
'<request-broker-message version="1.0">
<request class="UPDATE_ORGANISATION_HIERARCHY" culture="tr-TR">
<parameter name="OrgHierarchyDatasets_schema">
(here is not important...)
</parameter>
<parameter name="OrgHierarchyDatasets_diffgram">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<POSTN_ID>0000-0000H1-POS</POSTN_ID>
<ROLE_ID>0000-00002B-ROL</ROLE_ID>
<STATUS>1</STATUS>
</PositionRoles>
</NewDataSet>
</diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>
</request>
</request-broker-message>';
WITH XMLNAMESPACES ('urn:schemas-microsoft-com:xml-diffgram-v1' AS diffgr,
'urn:schemas-microsoft-com:xml-msdata' AS msdata)
SELECT dg.NDS.value('(PositionRoles/@diffgr:id)[1]','varchar(30)') AS id,
dg.NDS.value('(PositionRoles/@msdata:rowOrder)[1]','int') AS rowOrder,
dg.NDS.value('(PositionRoles/POSTN_ID/text())[1]','varchar(30)') AS POSTN_ID
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('request-broker-message/request/parameter/diffgr:diffgram/NewDataSet') dg(NDS);
我还删除了 NOLOCK
命中,因为我怀疑它被滥用了:Bad habits : Putting NOLOCK everywhere
我有一个 table,其中包含一个 XML 列,我正在尝试从 XML 数据中获取某些列。这些列位于 PositionRoles
标记下,该标记是 has INSERT
语句的一部分。不幸的是,我得到了 NULL
个值。
这是我使用的 XML 示例:
<request-broker-message version="1.0">
<request class="UPDATE_ORGANISATION_HIERARCHY" culture="tr-TR">
<parameter name="OrgHierarchyDatasets_schema">
(here is not important...)
</parameter>
<parameter name="OrgHierarchyDatasets_diffgram">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<POSTN_ID>0000-0000H1-POS</POSTN_ID>
<ROLE_ID>0000-00002B-ROL</ROLE_ID>
<STATUS>1</STATUS>
</PositionRoles>
</NewDataSet>
</diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>
</request>
</request-broker-message>
我的尝试:
;WITH XMLNAMESPACES('urn:schemas-microsoft-com:xml-diffgram-v1' AS diffgr,
'inserted' AS hasChanges)
INSERT INTO TMP_ORGANIZATION_HIERARCHY_LOGS_TABLE(POSITION_ID, OPERATION, ROLE_ID, PACKET_OWNER, RESPONSE_TIME)
SELECT
*
FROM TMP_PACKET_LOG_TABLE (NOLOCK)
WHERE
RESPONSE_PACKET.value('(/request-broker-message/request/parameter[@name="OrgHierarchyDatasets_diffgram"]//NewDataSet/hasChanges:PositionRoles/hasChanges:STATUS)[1]', 'varchar(1)') = '1'
不确定您所追求的具体价值是什么,但这应该足以让您到达那里。您需要在 WITH
中放置适当的名称空间( 不 以 ;
开头,语句以 1 结尾),然后在相关前缀具有相关命名空间名称的节点(例如 diffgr:
对应 diffgram
):
DECLARE @XML xml =
'<request-broker-message version="1.0">
<request class="UPDATE_ORGANISATION_HIERARCHY" culture="tr-TR">
<parameter name="OrgHierarchyDatasets_schema">
(here is not important...)
</parameter>
<parameter name="OrgHierarchyDatasets_diffgram">
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet>
<PositionRoles diffgr:id="PositionRoles1" msdata:rowOrder="0" diffgr:hasChanges="inserted">
<POSTN_ID>0000-0000H1-POS</POSTN_ID>
<ROLE_ID>0000-00002B-ROL</ROLE_ID>
<STATUS>1</STATUS>
</PositionRoles>
</NewDataSet>
</diffgr:diffgram>
</parameter>
<parameter name="ExistNodeCheck" type="System.Boolean">True</parameter>
</request>
</request-broker-message>';
WITH XMLNAMESPACES ('urn:schemas-microsoft-com:xml-diffgram-v1' AS diffgr,
'urn:schemas-microsoft-com:xml-msdata' AS msdata)
SELECT dg.NDS.value('(PositionRoles/@diffgr:id)[1]','varchar(30)') AS id,
dg.NDS.value('(PositionRoles/@msdata:rowOrder)[1]','int') AS rowOrder,
dg.NDS.value('(PositionRoles/POSTN_ID/text())[1]','varchar(30)') AS POSTN_ID
FROM (VALUES(@XML))V(X)
CROSS APPLY V.X.nodes('request-broker-message/request/parameter/diffgr:diffgram/NewDataSet') dg(NDS);
我还删除了 NOLOCK
命中,因为我怀疑它被滥用了:Bad habits : Putting NOLOCK everywhere