我在存储过程(SQL Server 2008)中有一个XML变量,其示例值为
<parent_node>
<category>Low</category>
<category>Medium</category>
<category>High</category>
</parent_node>
我必须将每个类别作为单独的记录插入表中。如何迭代XML并获取单个节点值?
如果我想调用存储过程并将每个类别作为输入参数发送,我们该怎么做?存储过程是遗留过程,一次只接受一个类别。我试图以这种方式调用程序。
任何帮助将不胜感激。
答案 0 :(得分:4)
这样的东西?
DECLARE @XmlVariable XML = '<parent_node>
<category>Low</category>
<category>Medium</category>
<category>High</category>
</parent_node>'
INSERT INTO dbo.YourTargetTable(CategoryColumn)
SELECT
XTbl.Cats.value('.', 'varchar(50)')
FROM
@XmlVariable.nodes('/parent_node/category') AS XTbl(Cats)
更新:如果您必须使用旧的旧存储过程并且无法更改它(这是我首选的方式),那么您必须这样做你自己循环的行(RBAR)循环,例如通过使用表变量:
-- declare temporary work table
DECLARE @RbarTable TABLE (CategoryName VARCHAR(50))
-- insert values into temporary work table
INSERT INTO @RbarTable(CategoryName)
SELECT
XTbl.Cats.value('.', 'varchar(50)')
FROM
@XmlVariable.nodes('/parent_node/category') AS XTbl(Cats)
-- declare a single category
DECLARE @CategoryNameToBeInserted VARCHAR(50)
-- get the first category
SELECT TOP 1 @CategoryNameToBeInserted = CategoryName FROM @RbarTable
-- as long as we have data
WHILE @CategoryNameToBeInserted IS NOT NULL
BEGIN
-- execute your stored procedure here.....
EXEC sp_executesql N'dbo.YourStoredProcedure @CategoryName',
N'@CategoryName VARCHAR(50)',
@CategoryName = @CategoryNameToBeInserted
-- delete the category we just inserted from the temporary work table
DELETE FROM @RbarTable WHERE CategoryName = @CategoryNameToBeInserted
-- see if we still have more categories to insert
SET @CategoryNameToBeInserted = NULL
SELECT TOP 1 @CategoryNameToBeInserted = CategoryName FROM @RbarTable ORDER BY CategoryName
END
答案 1 :(得分:0)
使用SQL Server中的XML,总有不止一种方法可以做到这一点。根据XML文档的大小以及查询它的次数,最好使用sp_xml_preparedocument
解析文档,为您提供引用它的句柄,然后您可以将其查询为很多时候和你想要的方式。这是你如何做到的:
declare @xml xml = '
<parent_node>
<category>Low</category>
<category>Medium</category>
<category>High</category>
</parent_node>'
declare @xml_handle int
exec sp_xml_preparedocument @xml_handle output, @xml
select value from openxml(@xml_handle, '/parent_node/category', 2) with (value varchar(100) 'text()') x
exec sp_xml_removedocument @xml_handle