2013-05-11 119 views
2

我有在存儲過程(SQL Server 2008的)一個XML變量,它的採樣值是迭代通過在SQL Server XML可變

<parent_node> 
    <category>Low</category> 
    <category>Medium</category> 
    <category>High</category> 
</parent_node> 

我必須採取每個類別並插入到表中,作爲單獨的記錄。如何迭代XML並獲取單個節點值?

如果我想調用一個存儲過程並將每個類別作爲輸入參數發送,我們該怎麼做?存儲過程是傳統存儲過程,它一次只接受一個類別。我正在嘗試以這種方式執行調用過程。

  1. 循環從xml變量中獲取單個類別。
  2. 用當前類別調用存儲過程。
  3. 轉移到下一個類別。
  4. 循環直到列表包含值。

任何幫助將不勝感激。

+0

向下選民請添加評論。我會幫你的。 – iamsumesh 2013-05-11 19:59:29

回答

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) 

更新:如果你必須使用舊的傳統的存儲過程,並不能改變它(這將是這樣做的我的首選方式),那麼你就必須做到以逐折騰-row(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 
+0

謝謝。一個小小的懷疑。如果我想調用存儲過程並將每個類別作爲輸入參數發送。我們如何做到這一點。存儲過程是傳統存儲過程,它只能同時接受一個類別。我正在以這種方式嘗試這一點。 循環 取從XML varable 調用存儲過程的單一類別與當前 類移動到下一個類別 循環,直到列表包含值 你有沒有獲取單個類別的任何想法。 – iamsumesh 2013-05-11 16:33:55

+0

@iamsumesh:你不能輕易做到這一點。 T-SQL是**基於集合的** - 它不太適合「遍歷項目列表併爲每行調用存儲過程」。如果你有這樣的話 - >你最好在你的前端代碼(C#,PHP,不管)中這麼做。在T-SQL中,最好重寫存儲過程以將單個XML作爲參數,並在其中包含一個單獨的'INSERT'語句。 – 2013-05-11 16:41:05

+0

舊存儲過程正在從另一個存儲過程中調用。我無權訪問前端代碼和舊版存儲過程代碼。從前端應用程序中,我們得到一個包含類別的xml變量。前端將調用我的存儲過程,並且此存儲過程將根據xml變量中的類別數量多次調用舊式存儲過程。任何建議來實現這一目標? – iamsumesh 2013-05-11 16:50:01

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 
+0

我喜歡這個想法,但如果我不知道它出現了多少次,該怎麼辦? http://stackoverflow.com/questions/26426412/how-to-ensure-the-sql-is-able-to-read-all-xml-tag-data – SearchForKnowledge 2014-10-17 14:17:31