第一種說明:
我看過這樣一篇文章,如下
在SQL Server2005中,微軟延續了 2000中一個特性(即支持XML類型的數據),並加強了對XML 數據列、XML變量以及XML索引的支持。
在數據庫中存儲XML數據是一個很出色的特征。對於大部分的數據處理需求來講,將XML數據格式化為其它關聯數據是十分重要。這也是引入OPENXML函 數的原因。OPENXML是一個SQL Server提供的函數,它的作用是接收XML數據,提供內存中 XML數據的行集視圖。
一個OPENXML函數用例
在下面的例子中,我們將演示如何使用OPENXML函數。假定我們現在正在從事一個網上購物系統開發。在這個場景中,顧客選擇登錄網站方式購買多種產品。 因為根據公司的商業模式,通過網站購物能夠節省成本。我們假定大部分的顧客都購買了七件或者更多的商品。我們的目標是當客戶頻繁的訪問網站的時候,要盡量 減少數據庫的調用。我們的想法是將網頁上提交的采購需求存儲為XML文檔,並且將其中的XML數據以字符串的形式傳送給數據庫底層的程序處理。這樣,我們 就可以在一次數據庫調用中將XML數據中的訂單信息插入數據庫中。
我們該如何解決上面的問題呢?首先我們看看將要編輯的網頁數據。一個簡單的XML文檔含有來自網站的很多核心信息,包括:產品名稱、價格、日期以及顧客資料。列表A包含了一個簡單的XML數據流。
<ShoppingCart> <Purchase ProductID= "7 " Price= "10.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "99 " Price= "25.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "32 " Price= "12.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "11 " Price= "90.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "7 " Price= "50.00 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "8 " Price= "67.35 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "45 " Price= "29.99 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> <Purchase ProductID= "54 " Price= "49.49 " SaleDate= "10/11/2006 " SaleBatchID = "4523 " CustomerID = "2398 "/> </ShoppingCart>
列表A
然后,我們需要設計一個網頁接口提供存儲程序的調用。通過調用這一存儲程序,將XML數據流存儲至數據庫。列表B是這一存儲程序的實現內容。
CREATE PROCEDURE usp_InsertShoppingCartOrder ( @xml XML ) AS BEGIN DECLARE @Pointer INT EXECUTE sp_xml_preparedocument @Pointer OUTPUT,@xml INSERT INTO WebSales ( ProductID, SalePrice, SaleDate, SaleBatchID, CustomerID ) SELECT ProductID, Price, SaleDate, SaleBatchID, CustomerID FROM OPENXML (@Pointer, '/ShoppingCart/Purchase ') WITH ( ProductID INT, Price MONEY, SaleDate SMALLDATETIME, SaleBatchID INT, CustomerID INT ) EXEC sp_xml_removedocument @Pointer END
列表B
這一存儲程序支持XML數據類型(SQL Server 2005中新特色)作為輸入參數(我們也可以使用變量字符數據類型作為我們的輸入參數,例如VARCHAR (max)或者定義VARCHAR數據類型)。
接下來,我們調用系統程序sp_xml_preparedocument,它不僅創建了XML文檔在內存中的表示,也允許XML文檔作為調用參數。一旦我 們擁有了指向內存中XML文檔的句柄,就可以調用OPENXML函數。在函數調用中使用不同的參數,還可以對XML數據的返回結果集進行詳細的控制。
我們提供指向XML文檔的句柄,並且通過XPATH查詢返回想要的XML數據中的節點。OPENXML函數中的WITH子句允許指定返回數據的行集格式。 一旦將數據插入到websales 表格中,就可以調用系統程序sp_xml_removedocument刪除SQL Server 服務器內存中的XML數據。
這個簡單的例子演示了通過OPENXML函數來減少數據庫調用次數的強大功能。OPENXML函數提供很大的靈活性,你既可以將所有的XML數據插入到 SQL Server 數據表中,也可以拆分XML文件,將其插入到不同的SQL Server數據表中。通過這一技術,我們就可以在一次程序調用中插入8條記錄,而不是像傳統的技術那樣,要通過8次操作實現。
OPENXML的局限性
調用OPENXML函數時要注意內存的使用情況。系統程序sp_xml_preparedocument 的返回值是指向內存中XML文檔的句柄。所以,你最好不要使用OPENXML加載較大的XML文檔,因為那樣可能會造成服務器的內存溢出。
在以后的文章中,我將會向你介紹如何使用SQL Server 2005提供的關於XML的一些新屬性,這些新屬性不僅能夠實現OPENXML函數的功能,而且不需要考慮OPENXML調用時產生的內存操作問題。
作者簡介
Tim Chapman先生在一家位於Louisville, KY的銀行從事數據庫管理員的工作,擁有7年的IT工作經驗。他還通過了微軟的SQL Server 2000和SQL Server 2005認證。
第二種說明:
創建幾個帶不同參數的存儲過程去完成同一樣任務對我們來說一直以來都是一個負擔。通過使用XML字符串傳遞參數給你的存儲過程可以簡化這個任務,從而使設計COM組件變得更加簡單。
達 到這個目標的方法是將你的參數作為一個XML字符串傳入,然后解析XML以取得你需要的數據,最后繼續完成你需要實現的功能。你不但可以從XML中獲得參 數,你還可以在由XML創建的DOM文檔運行查詢語句,完成幾個存儲過程調用。我將給出一些例子來說明怎樣做,每個例子都有一個簡單的解釋。
在這個例子中,我將傳遞一些參數用以更新Customer表的name域。XML被解析以獲得customerid(標識列)和新的name。我傳給過程的XML字符串如下:
<root> <Customer> <customerid>3</customerid> <name>Acme Inc.</name> </Customer> </root>
創建的存儲過程如下:
CREATE PROCEDURE update_Customer (@xmldata varchar(8000)) AS DECLARE @customerid int DECLARE @customername varchar(50) DECLARE @xmldata_id int EXEC sp_xml_preparedocument @xmldata_id OUTPUT, @xmldata, '' SELECT @customerid = customerid, @customername = [name] FROM OPENXML(@xmldata_id, '//Customer', 2) WITH (customerid int, [name] varchar(50)) EXEC sp_xml_removedocument @xmldata_id UPDATE Customer SET Customer.[name] = ISNULL(@customername, Customer.[name]) WHERE Customer.tblID = @customerid
這個過程首先聲明我們用於存儲相關信息的變量。之后,打開DOM文檔,調用過程sp_xml_preparedocument,其第一個參數返回一個“句柄”。
這個過程調用的第二個參數是新DOM文檔的XML源。第一個參數返回的“句柄”在OPENXML調用中用於查詢DOM文檔。OPENXML調用的第二個參數是一個映射到包含要提取數據的父節點的擴展路徑。
第三個參數(2)指明使用以元素為中心的映射。WITH子句為被解析的數據提供行集合格式,然后sp_xml_removedocument調用刪除DOM文檔資源。
在下面的另一個例子中,我將會根據傳入的一組customer ID刪除幾行數據。使用的XML字符串如下:
<root> <Customer> <customerid>1</customerid> </Customer> <Customer> <customerid>2</customerid> </Customer> <Customer> <customerid>3</customerid> </Customer> </root>
使用的存儲過程如下:
EXEC sp_xml_preparedocument @xml_id OUTPUT, @xmldata, '' DELETE FROM Customer WHERE Customer.tblID IN (SELECT customerid FROM OPENXML (@xmldata_id, '//Customer', 2) WITH (customerid int))
這個存儲過程的使用避免了建立一個長SQL查詢字符串來通過ADO傳遞,或者多次調用同一個存儲過程。也避免了由於多次調用引起的網絡擁擠。
正如你看到的,使用Microsoft SQL Server 2000可以使一些事情變得比較簡單。但記住是當你在SQL Server 2000中使用XML時,作為參數傳入的XML不能超過8000個字符。就像常說的,不要過高的看待一件好事的好處。
參考MSDN庫取得更多關於OPENXML, sp_xml_preparedocument 和 sp_xml_removedocument 的信息。