嗨,我需要有关以下sql的帮助:
我需要以这种格式创建一个xml文件
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRpt> <GrpHdr> <MsgId></MsgId> </GrpHdr> <OrgnlGrpInfAndSts> <OrgnlMsgId /> </OrgnlGrpInfAndSts> </FIToFIPmtStsRpt> </document>
目前,我有一个包含主要信息的变量,并且我在两者之间建立了信息(可以将grphdr插入到具有不同信息的主要xml中多次)
declare @xml xml='<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRpt> </FIToFIPmtStsRpt> </Document> ' declare @xmlgrp xml='<GrpHdr> <MsgId></MsgId> </GrpHdr>' --here i do some code to fill msgid
然后当我将grphdr添加回主xml中时
SET @xml.modify ('declare namespace a= "urn:iso:std:iso:20022:tech:xsd:001.002.001.04"; insert sql:variable("@xmlgrp") into (a:Document/a:FIToFIPmtStsRpt)[1]') select @xml
我需要弄清楚顶级文件格式,但现在发生的情况是以下给出的
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRpt> <GrpHdr xmlns="">-- i need this xmlns tag out <MsgId /> </GrpHdr> </FIToFIPmtStsRpt> </Document>
不知何故,我需要xml中的空xmlns标记。我无法转换为varchar(max)来删除,因为我们的数据库将变量限制为8000个字符,并且我的xml可以增长到超过8000个。1个文件中可以有多个grphdr或OrgnlGrpInfAndSts
table: lim_Live_Inbound lim_msg_id | lim_request_transaction_id | client_name ------------------------------------------------------ 021/00210006/20160225/000002 | 00012016-02-25000000023 | Mr Piet 021/00210006/20160225/000002 | 00012016-02-25000000022 | Mrs Name
必须产生这样的
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRpt> <GrpHdr> <MsgId>021/00210006/20160225/000002</MsgId> </GrpHdr> <OrgnlGrpInfAndSts> <OrgnlMsgId>00012016-02-25000000023</OrgnlMsgId> <name>Mr Piet</name> </OrgnlGrpInfAndSts> <OrgnlGrpInfAndSts> <OrgnlMsgId>00012016-02-25000000022</OrgnlMsgId> <name>Mrs Name</name> </OrgnlGrpInfAndSts> </FIToFIPmtStsRpt> </document>
这就是为什么我要尝试插入xml的原因。如果有人能以更好的方式帮助我,将不胜感激。
实际上,这种解决方法仍然没有真正的帮助。命名空间xmlns=""被视为*内部的所有 内容都不在命名空间之内…您可以将结果转换为NVARCHAR(MAX)并用于REPLACE摆脱xmlns=""。然后,您可以将字符串重新转换为XML。对于Microsoft,感到羞耻的是10(!!)年的问题(请参阅下面的链接)仍未解决。请去那里投票!
xmlns=""
NVARCHAR(MAX)
REPLACE
XML
DECLARE @lim_Live_Inbound TABLE(lim_msg_id VARCHAR(100),lim_request_transaction_id VARCHAR(100),client_name VARCHAR(100)); INSERT INTO @lim_Live_Inbound VALUES ('021/00210006/20160225/000002','00012016-02-25000000023','Mr Piet') ,('021/00210006/20160225/000002','00012016-02-25000000022','Mrs Name'); DECLARE @nestedXMLs TABLE(MsgId VARCHAR(100),nestedXML XML); WITH GrpMsg AS ( SELECT DISTINCT lim_msg_id AS MsgId FROM @lim_Live_Inbound ) INSERT INTO @nestedXMLs SELECT MsgId ,( SELECT innerTbl.lim_request_transaction_id AS OrgnlMsgId ,innerTbl.client_name AS name FROM @lim_Live_Inbound AS innerTbl WHERE innerTbl.lim_msg_id=GrpMsg.MsgId FOR XML PATH('OrgnlGrpInfAndSts'),TYPE ) FROM GrpMsg; WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04') ,GrpMsg AS ( SELECT DISTINCT lim_msg_id AS MsgId FROM @lim_Live_Inbound ) SELECT GrpMsg.MsgId AS [GrpHdr/MsgId] ,n.nestedXML AS [node()] FROM GrpMsg INNER JOIN @nestedXMLs AS n ON GrpMsg.MsgId=n.MsgId FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
结果
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRp> <GrpHdr> <MsgId>021/00210006/20160225/000002</MsgId> </GrpHdr> <OrgnlGrpInfAndSts xmlns=""> <OrgnlMsgId>00012016-02-25000000023</OrgnlMsgId> <name>Mr Piet</name> </OrgnlGrpInfAndSts> <OrgnlGrpInfAndSts xmlns=""> <OrgnlMsgId>00012016-02-25000000022</OrgnlMsgId> <name>Mrs Name</name> </OrgnlGrpInfAndSts> </FIToFIPmtStsRp> </Document>
您将CAST(REPLACE(CAST(TheXMLHere AS NVARCHAR(MAX)),' xmlns=""','') AS XML)用来摆脱错误的空名称空间。
CAST(REPLACE(CAST(TheXMLHere AS NVARCHAR(MAX)),' xmlns=""','') AS XML)
这是重复命名空间- 但这在语法上是正确的,但很烦人(请参阅:https://connect.microsoft.com/SQLServer/feedback/details/265956/suppress- namespace-attributes-in-nested-select-for- xml语句)
DECLARE @lim_Live_Inbound TABLE(lim_msg_id VARCHAR(100),lim_request_transaction_id VARCHAR(100),client_name VARCHAR(100)); INSERT INTO @lim_Live_Inbound VALUES ('021/00210006/20160225/000002','00012016-02-25000000023','Mr Piet') ,('021/00210006/20160225/000002','00012016-02-25000000022','Mrs Name'); WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04') ,GrpMsg AS ( SELECT DISTINCT lim_msg_id AS MsgId FROM @lim_Live_Inbound ) SELECT MsgId AS [GrpHdr/MsgId] ,( SELECT innerTbl.lim_request_transaction_id AS OrgnlMsgId ,innerTbl.client_name AS name FROM @lim_Live_Inbound AS innerTbl WHERE innerTbl.lim_msg_id=GrpMsg.MsgId FOR XML PATH('OrgnlGrpInfAndSts'),TYPE ) FROM GrpMsg FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRp> <GrpHdr> <MsgId>021/00210006/20160225/000002</MsgId> </GrpHdr> <OrgnlGrpInfAndSts xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <OrgnlMsgId>00012016-02-25000000023</OrgnlMsgId> <name>Mr Piet</name> </OrgnlGrpInfAndSts> <OrgnlGrpInfAndSts xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <OrgnlMsgId>00012016-02-25000000022</OrgnlMsgId> <name>Mrs Name</name> </OrgnlGrpInfAndSts> </FIToFIPmtStsRp> </Document>
我不知道您的数据来自哪里,但是-绝对采用硬编码-这是一种方法:
WITH XMLNAMESPACES(DEFAULT 'urn:iso:std:iso:20022:tech:xsd:001.002.001.04') SELECT 0 AS [GrpHdr/MsgId] ,0 AS [OrgnlGrpInfAndSts/OrgnlMsgId] FOR XML PATH('FIToFIPmtStsRp'),ROOT('Document')
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:001.002.001.04"> <FIToFIPmtStsRp> <GrpHdr> <MsgId>0</MsgId> </GrpHdr> <OrgnlGrpInfAndSts> <OrgnlMsgId>0</OrgnlMsgId> </OrgnlGrpInfAndSts> </FIToFIPmtStsRp> </Document>