我有以下XML结构:
set @MailXML =
'<MailingCompany>
<Mailman>
<Name>Jamie</Name>
<Age> 24 </Age>
<Letter>
<DestinationAddress> 440 Mountain View Parade </DestinationAddress>
<DestinationCountry> USA </DestinationCountry>
<OriginCountry> Australia </OriginCountry>
<OriginAddress> 120 St Kilda Road </OriginAddress>
</Letter>
</Mailman>
</MailingCompany>'
我的SQL目前看起来像这样:
-- Mail Insertion
INSERT INTO mailDB.dbo.Mailman
SELECT
m.value('Name[1]','varchar(50)') as Name,
m.value('Age[1]','varchar(50)') as Age
FROM
@MailXML.nodes('/MailingCompany/Mailman') as A(m)
SET @MailPersonFK = SCOPE_IDENTITY();
-- Letter Insertion
INSERT INTO mailDB.dbo.Letter
SELECT
l.value('DestinationAddress[1]', 'varchar(50)') as DestinationAddress,
l.value('DestinationCountry[1]', 'varchar(50)') as DestinationCountry,
l.value('OriginCountry[1]', 'varchar(50)') as OriginCountry,
l.value('OriginAddress[1]', 'varchar(50)') as OriginAddress
@MailPersonFK as MailID
FROM
@MailXML.nodes('MailingCompany/Mailman/Letter') as B(l)
我正在尝试将Mailman
和Letter数据提取到各自的表中。我有这个工作,但我的问题是MailCompany
节点是动态的。有时它可能是MailVehicle
,例如,我仍然需要
读取相应的Mailman
和Letter
节点数据,并将它们插入各自的表中。
所以两者
FROM @MailXML.nodes('/MailingCompany/Mailman') as A(t)
和
FROM @MailXML.nodes('MailingCompany/Mailman/Letter') as B(l)
需要更改以允许MailingCompany
动态。
我试图提取父节点并将其连接成一个字符串,以便放入.nodes函数中,如下所示:
set @DynXML = '/' + @parentNodeVar + '/Mailman'
FROM @MailXML.nodes(@DynXML) as A(t)
但是我收到以下错误:
XML数据类型方法“nodes”的参数1必须是字符串文字。
如何克服这种动态XML问题?
非常感谢您提前
答案 0 :(得分:3)
看看这个简化的例子:
DECLARE @xml1 XML=
N'<MailingCompany>
<Mailman>
<Name>Jamie</Name>
<Letter>
<DestinationAddress> 440 Mountain View Parade </DestinationAddress>
</Letter>
</Mailman>
</MailingCompany>';
DECLARE @xml2 XML=
N'<OtherName>
<Mailman>
<Name>Jodie</Name>
<Letter>
<DestinationAddress> This is the other address </DestinationAddress>
</Letter>
</Mailman>
</OtherName>';
SELECT @xml1.value(N'(*/Mailman/Name)[1]','nvarchar(max)') AS Mailman_Name
,@xml1.value(N'(*/Mailman/Letter/DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
SELECT @xml2.value(N'(*/Mailman/Name)[1]','nvarchar(max)') AS Mailman_Name
,@xml2.value(N'(*/Mailman/Letter/DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
您可以使用*
替换节点的名称。
另一个技巧是带有//
的深度搜索(与之前的结果相同):
SELECT @xml1.value(N'(//Name)[1]','nvarchar(max)') AS Mailman_Name
,@xml1.value(N'(//DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
SELECT @xml2.value(N'(//Name)[1]','nvarchar(max)') AS Mailman_Name
,@xml2.value(N'(//DestinationAddress)[1]','nvarchar(max)') AS DestinationAddress
一般规则:尽可能具体。