2013-09-25 42 views
2

我一直在使用XML将大量数据导入SQL一段时间,但我想知道是否有可能从单个XML文件跨多个表导入数据孩子节点?使用XML将关系数据导入到SQL Server中

考虑这个例子:

DECLARE @tbl_makes TABLE (ID int IDENTITY(1,1), makeName nvarchar(100)) 
INSERT INTO @tbl_makes (makeName) VALUES ('Ford') 
INSERT INTO @tbl_makes (makeName) VALUES ('Jaguar') 

DECLARE @tbl_models TABLE (ID int IDENTITY(1,1), makeID int, modelName nvarchar(100)) 
INSERT INTO @tbl_models (makeID, modelName) VALUES (1, 'Escort') 
INSERT INTO @tbl_models (makeID, modelName) VALUES (1, 'Sierra') 
INSERT INTO @tbl_models (makeID, modelName) VALUES (2, 'XK') 
INSERT INTO @tbl_models (makeID, modelName) VALUES (2, 'XJS') 

SELECT * FROM @tbl_makes m INNER JOIN @tbl_models md ON m.ID = md.makeID 

DECLARE @xml XML = ' 
<cars> 
    <make name="Ford"> 
     <model name="Mustang" /> 
     <model name="Taurus" /> 
     <model name="F350" /> 
    </make> 
    <make name="Aston Martin"> 
     <model name="Vanquish" /> 
     <model name="DB7" /> 
     <model name="Lagonda" /> 
    </make> 
</cars>' 

我明白,厂名名称将需要插入/查到的第一个前可以插入相关数据。我在网上搜索了这个答案,但例子只使用一个表。我猜这是不可能的,如果没有使用各种临时表,但这里...

回答

6

这样的解决方案呢?

INSERT INTO @tbl_makes (makeName) 
SELECT i.i.value('@name', 'nvarchar(100)') 
FROM @xml.nodes('/cars[1]/make')i(i) 
LEFT JOIN @tbl_makes MA on i.i.value('@name', 'nvarchar(100)') = MA.makeName 
WHERE MA.ID IS NULL; 

INSERT INTO @tbl_models (makeID, modelName) 
SELECT MA.ID, j.j.value('@name', 'nvarchar(100)') 
FROM @xml.nodes('/cars[1]/make')i(i) 
INNER JOIN @tbl_makes MA ON i.i.value('@name', 'nvarchar(100)') = MA.makeName 
CROSS APPLY i.i.nodes('model')j(j) 
LEFT JOIN @tbl_models MO on j.j.value('@name', 'nvarchar(100)') = MO.modelName 
WHERE MO.ID IS NULL; 
+0

哇。精湛的答案。你能解释一下CROSS APPLY部分吗?是不是因为你不能连接到一个XML对象值?另外,OUTER APPLY对逻辑有什么影响吗? – EvilDr

+1

CROSS APPLY和nodes()帮助从XML文档创建一个类似于表的实体。 XPath表达式返回一些元素,并且每个元素都与单个行关联。只有在汽车制造商没有提到任何汽车的情况下,您才可能需要外部申请。 – GriGrim

+0

非常好,再次感谢。 – EvilDr

相关问题