将 XML 格式数据存储在 SQL 服务器 table
Store XML format data in SQL Server table
我的查询是:
Declare @xml1 xml='
<Root>
<Dir Name="Test">
<Dir Name="Test1">
<File>File1<Size>375</Size></File>
<File>File2<Size>375</Size></File>
<File>File3<Size>375</Size></File>
<File>File4<Size>375</Size></File>
<File>File5<Size>375</Size></File>
<File>File6<Size>375</Size></File>
</Dir>
<Dir Name="Test2" />
</Dir>
</Root>'
Declare @t table (xmld xml)
Insert into @t values (@xml1)
select * from @t
我想将 XML 数据存储在 SQL 服务器 table 中。
我的预期输出是:
FolderPath FileName FileSize
--------------------------------
Test - -
Test\Test1 File1 375
Test\Test1 File2 375
Test\Test1 File3 375
Test\Test1 File4 375
Test\Test1 File5 375
Test\Test2 - -
我按照thislink参考了,但没看懂。
有人可以帮我解决这个问题吗?
我提议更好的 XML 结构,不使用名称空间作为目录名称。甚至 <File>
标签在原始 XML.
中也不那么干净
SQL
DECLARE @xml xml=
N'<Root>
<Dir name="Test">
<Dir name="Test1">
<File name="File1" Size="375"/>
<File name="File2" Size="375"/>
<File name="File3" Size="375"/>
</Dir>
<Dir name="Test2">
<File name="File1" Size="575"/>
<File name="File2" Size="75"/>
<File name="File3" Size="75"/>
</Dir>
<Dir name="Test3"/>
</Dir>
</Root>';
SELECT dir.c.value('@name','VARCHAR(100)') + '\' +
subdir.c.value('@name','VARCHAR(100)') AS folderPath
, fil.c.value('@name','VARCHAR(100)') AS [fileName]
, fil.c.value('@Size','VARCHAR(100)') AS [fileSize]
FROM @xml.nodes('/Root/Dir') AS dir(c)
CROSS APPLY dir.c.nodes('Dir') AS subdir(c)
OUTER APPLY subdir.c.nodes('File') AS fil(c)
ORDER BY folderPath, [fileName];
Output
+------------+----------+----------+
| folderPath | fileName | fileSize |
+------------+----------+----------+
| Test\Test1 | File1 | 375 |
| Test\Test1 | File2 | 375 |
| Test\Test1 | File3 | 375 |
| Test\Test2 | File1 | 575 |
| Test\Test2 | File2 | 75 |
| Test\Test2 | File3 | 75 |
| Test\Test3 | NULL | NULL |
+------------+----------+----------+
Declare @xml1 xml='
<Root>
<Dir xmlns="Test">
<Dir xmlns="Test1">
<File>File1<Size>175</Size></File>
<File>File2<Size>275</Size></File>
<File>File3<Size>375</Size></File>
<File>File4<Size>475</Size></File>
<File>File5<Size>575</Size></File>
<File>File6<Size>675</Size></File>
</Dir>
<Dir xmlns="Test2" />
</Dir>
</Root>';
select
dr.d.value('namespace-uri(.)', 'nvarchar(100)') as thedir,
fl.f.value('text()[1]', 'nvarchar(100)') as thefile,
fl.f.value('*:Size[1]', 'nvarchar(100)') as thesize
from @xml1.nodes('//*:Dir') as dr(d)
outer apply dr.d.nodes('./*:File') as fl(f);
Declare @xml2 xml='
<Root>
<Dir Name="Test">
<Dir Name="Test1">
<File>File1<Size>101375</Size></File>
<File>File2<Size>102375</Size></File>
<File>File3<Size>103375</Size></File>
<File>File4<Size>104375</Size></File>
<File>File5<Size>105375</Size></File>
<File>File6<Size>106375</Size></File>
</Dir>
<Dir Name="Test2" />
</Dir>
</Root>';
select
dr.d.value('@Name[1]', 'nvarchar(100)') as thedir,
fl.f.value('text()[1]', 'nvarchar(100)') as thefile,
fl.f.value('*:Size[1]', 'nvarchar(100)') as thesize
from @xml2.nodes('//Dir') as dr(d)
outer apply dr.d.nodes('./File') as fl(f);
我的查询是:
Declare @xml1 xml='
<Root>
<Dir Name="Test">
<Dir Name="Test1">
<File>File1<Size>375</Size></File>
<File>File2<Size>375</Size></File>
<File>File3<Size>375</Size></File>
<File>File4<Size>375</Size></File>
<File>File5<Size>375</Size></File>
<File>File6<Size>375</Size></File>
</Dir>
<Dir Name="Test2" />
</Dir>
</Root>'
Declare @t table (xmld xml)
Insert into @t values (@xml1)
select * from @t
我想将 XML 数据存储在 SQL 服务器 table 中。
我的预期输出是:
FolderPath FileName FileSize
--------------------------------
Test - -
Test\Test1 File1 375
Test\Test1 File2 375
Test\Test1 File3 375
Test\Test1 File4 375
Test\Test1 File5 375
Test\Test2 - -
我按照thislink参考了,但没看懂。
有人可以帮我解决这个问题吗?
我提议更好的 XML 结构,不使用名称空间作为目录名称。甚至 <File>
标签在原始 XML.
SQL
DECLARE @xml xml=
N'<Root>
<Dir name="Test">
<Dir name="Test1">
<File name="File1" Size="375"/>
<File name="File2" Size="375"/>
<File name="File3" Size="375"/>
</Dir>
<Dir name="Test2">
<File name="File1" Size="575"/>
<File name="File2" Size="75"/>
<File name="File3" Size="75"/>
</Dir>
<Dir name="Test3"/>
</Dir>
</Root>';
SELECT dir.c.value('@name','VARCHAR(100)') + '\' +
subdir.c.value('@name','VARCHAR(100)') AS folderPath
, fil.c.value('@name','VARCHAR(100)') AS [fileName]
, fil.c.value('@Size','VARCHAR(100)') AS [fileSize]
FROM @xml.nodes('/Root/Dir') AS dir(c)
CROSS APPLY dir.c.nodes('Dir') AS subdir(c)
OUTER APPLY subdir.c.nodes('File') AS fil(c)
ORDER BY folderPath, [fileName];
Output
+------------+----------+----------+
| folderPath | fileName | fileSize |
+------------+----------+----------+
| Test\Test1 | File1 | 375 |
| Test\Test1 | File2 | 375 |
| Test\Test1 | File3 | 375 |
| Test\Test2 | File1 | 575 |
| Test\Test2 | File2 | 75 |
| Test\Test2 | File3 | 75 |
| Test\Test3 | NULL | NULL |
+------------+----------+----------+
Declare @xml1 xml='
<Root>
<Dir xmlns="Test">
<Dir xmlns="Test1">
<File>File1<Size>175</Size></File>
<File>File2<Size>275</Size></File>
<File>File3<Size>375</Size></File>
<File>File4<Size>475</Size></File>
<File>File5<Size>575</Size></File>
<File>File6<Size>675</Size></File>
</Dir>
<Dir xmlns="Test2" />
</Dir>
</Root>';
select
dr.d.value('namespace-uri(.)', 'nvarchar(100)') as thedir,
fl.f.value('text()[1]', 'nvarchar(100)') as thefile,
fl.f.value('*:Size[1]', 'nvarchar(100)') as thesize
from @xml1.nodes('//*:Dir') as dr(d)
outer apply dr.d.nodes('./*:File') as fl(f);
Declare @xml2 xml='
<Root>
<Dir Name="Test">
<Dir Name="Test1">
<File>File1<Size>101375</Size></File>
<File>File2<Size>102375</Size></File>
<File>File3<Size>103375</Size></File>
<File>File4<Size>104375</Size></File>
<File>File5<Size>105375</Size></File>
<File>File6<Size>106375</Size></File>
</Dir>
<Dir Name="Test2" />
</Dir>
</Root>';
select
dr.d.value('@Name[1]', 'nvarchar(100)') as thedir,
fl.f.value('text()[1]', 'nvarchar(100)') as thefile,
fl.f.value('*:Size[1]', 'nvarchar(100)') as thesize
from @xml2.nodes('//Dir') as dr(d)
outer apply dr.d.nodes('./File') as fl(f);