SQL openXML如何用于循环

时间:2011-10-25 14:03:56

标签: sql sql-server sql-server-2008

这是我的代码我在逐个插入xml元素值时遇到问题。 如何为这个

进行循环
DECLARE @x VARCHAR(8000)
SET @x = 
  '<authors>
    <author>
        <firstname>Michael</firstname>
        <lastname>Howard</lastname>
    </author>
    <author>
        <firstname>David</firstname>
        <lastname>LeBlanc</lastname>
    </author>
    <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
     <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
   </authors>'

DECLARE @h INT
DECLARE @h1 VARCHAR(MAX)
EXECUTE sp_xml_preparedocument @h OUTPUT, @x 

SELECT @h1= firstname 
FROM OPENXML(@h, '/authors/author',2)
WITH(
    firstname VARCHAR(20)

)
select NAME from temps WHERE NAME=@h1 
if @@ROWCOUNT=0
Begin
INSERT INTO temps(NAME)  VALUES (@h1)
END
EXECUTE sp_xml_removedocument @h 

现在我的代码只插入了我想要一个接一个地执行的最后一个xml元素..告诉我解决方案或想法

4 个答案:

答案 0 :(得分:1)

 DECLARE @x XML  = '<authors>
  <author>
    <firstname>Michael</firstname>
    <lastname>Howard</lastname>
  </author>
  <author>
    <firstname>David</firstname>
    <lastname>LeBlanc</lastname>
  </author>
  <author>
    <firstname>adad</firstname>
    <lastname>asdad</lastname>
  </author>
  <author>
    <firstname>adad</firstname>
    <lastname>asdad</lastname>
  </author>
</authors>'

 SELECT T.c.value('./firstname[1]', 'varchar(200)')
 FROM @x.nodes('/authors/author') AS T(c)

答案 1 :(得分:0)

您还没有描述为什么您正在处理XML,所以我猜。您似乎在firstname表中查找特定的temps值,如果找不到,则添加它。我将演示一个表变量@names

-- Assume you have a table [temps] with
-- a column [name], and you want to find
-- the new/missing firstnames from an XML
-- fragment and insert the new firstnames into
-- the [temps] table
-- Example:
--DECLARE [temps] TABLE (name VARCHAR(20))
--INSERT [temps] (name) VALUES ('Michael')

-- Create a temporary table to hold the XML firstname values
DECLARE @names TABLE (firstname VARCHAR(20))
DECLARE @x xml
SET @x =  
  '<authors> 
    <author> 
        <firstname>Michael</firstname> 
        <lastname>Howard</lastname> 
    </author> 
    <author> 
        <firstname>David</firstname> 
        <lastname>LeBlanc</lastname> 
    </author> 
    <author> 
        <firstname>adad</firstname> 
        <lastname>asdad</lastname> 
    </author> 
     <author> 
        <firstname>adad</firstname> 
        <lastname>asdad</lastname> 
    </author> 
   </authors>' 

-- Extract the firstnames from the XML and insert the names
-- into the temp table variable
INSERT INTO @names(firstname)
SELECT  x.author.value('firstname[1]', 'varchar(20)') AS firstname
FROM    @x.nodes('/authors/author') AS x(author)

-- Use a left outer join query to identify the new/missing names
-- in the temp table and then insert the names into [temps].
-- The WHERE condition specifies rows that exist in @firstnames
-- but do not exist (are NULL) in [temps].
INSERT  temps (name)
SELECT  nam.firstname
FROM    @names      nam  LEFT OUTER JOIN
        temps       tmp  ON (nam.firstname = tmp.name)
WHERE   tmp.name IS NULL

LEFT OUTER JOIN与WHERE条件一起使用来标识@firstnames表变量中的firstnames而不是[firstnames]表中的firstnames。尽可能避免迭代SQL中的数据并尝试使用基于集合的操作。

答案 2 :(得分:0)

如果您这样做:

 DECLARE @x xml
SET @x = 
  '<authors>
    <author>
        <firstname>Michael</firstname>
        <lastname>Howard</lastname>
    </author>
    <author>
        <firstname>David</firstname>
        <lastname>LeBlanc</lastname>
    </author>
    <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
     <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
   </authors>'

SELECT 
  ref.value('firstname[1]', 'NVARCHAR(20)') AS firstname ,
  ref.value('lastname[1]', 'NVARCHAR (10)') AS lastname ,
  ROW_NUMBER() over (order by ref.value('firstname[1]', 'NVARCHAR(20)')) AS rownum 

FROM @x.nodes('/authors/author') 
xmlData( ref )

Which prints: 
firstname            lastname   rownum
-------------------- ---------- --------------------
adad                 asdad      1
adad                 asdad      2
David                LeBlanc    3
Michael              Howard     4

您可以轻松地执行insert into ...而不是循环

注意我添加了row_num,因为看起来您只想从我从查询中理解的内容中插入第二行的值

答案 3 :(得分:0)

  

得到答案.........

DECLARE @x VARCHAR(8000),
        @nItemCnt int
DECLARE @ProductID VARCHAR(MAX),
        @lcnt INT
DECLARE @@getCurrentName CURSOR,
@h INT,
@h1 VARCHAR(MAX)
SET @x = 
  '<authors>
    <author>
        <firstname>Michael</firstname>
        <lastname>Howard</lastname>
    </author>
    <author>
        <firstname>David</firstname>
        <lastname>LeBlanc</lastname>
    </author>
    <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
     <author>
        <firstname>adad</firstname>
        <lastname>asdad</lastname>
    </author>
   </authors>'


EXECUTE sp_xml_preparedocument @h OUTPUT, @x 
SET @@getCurrentName = CURSOR FOR SELECT firstname FROM OPENXML(@h, '/authors/author',2)WITH(firstname VARCHAR(20))
OPEN @@getCurrentName
FETCH NEXT FROM @@getCurrentName INTO @ProductID
WHILE @@FETCH_STATUS = 0
BEGIN
select @lcnt=COUNT(name) from temps WHERE name=@ProductID
if @lcnt=0 
insert into temps values(@ProductID)
PRINT @ProductID
FETCH NEXT
FROM @@getCurrentName INTO @ProductID
END
CLOSE @@getCurrentName
DEALLOCATE @@getCurrentName