使用XML在SQL Server上創建計算列

 在SQL Server數據庫中,當你想使用一個數據,而這個數據不保存在表中,計算列很有用。例如,你有一張表,它包括列dollar amounts, wholesale prices和retail prices。你肯定不想在每次查詢表時來計算那兩列之間的差值,你希望將其值保存在第三列中,讓其自動計算前兩列之間的差值。而此列就是計算列。

  在SQL Server中使用XML數據來創建計算列,你的列定義必須包含必要的用來檢測向列中插入的是什麼數據的表達式。例如,在上面的例子中,你的表達式應該從retail列中的值減去wholesale列中的值。當你添加或更新表中的數據行時,差值將自動插入至計算列中。

  你可以很容易地在兩個或更多的包含字符串或數字類型值的列的基礎上創建計算列。(更多關於如何創建此類型的計算列的詳細信息,請參考Microsoft SQL Server Books Online)。然而,如果你想要基於指定的XML列中元素值創建一個計算列,該過程相對更加複雜一些。因爲你必須使用Xquery表達式來從XML列中獲取指定元素數據,且SQL Server不支持在計算列的定義中使用Xquery表達式。

  要解決此問題,可以創建一個函數來接收你想包含在計算列中的XML數據,並在計算列定義中調用此函數。更好的示範這是如何工作的,我們在這給出一個例子。我在SQL Server 2005的示例數據庫AdventureWorks中創建以下的架構和表:

  USE AdventureWorks;

  
GO

  
CREATE SCHEMA hr

  
GO

  
SELECT TOP 10 JobCandidateID AS CandidateID,

  
[Resume] AS JobResume

  
INTO hr.CandidateNames

  
FROM HumanResources.JobCandidate

  
GO

  正如名稱所示,HumanResources.JobCandidate表中的Resume列是一個XML列,它包含侯選人的履歷信息。我從這張表中提取數據來創建hr架構中的CandidateNames表。(我創建了一個單獨的表,因爲我希望可以修改表定義,從而可以增加計算列) 在建立好測試環境後,你可以創建函數。函數應該包括在從指定的XML列中獲取數據時所需的XQuery表達式。例如,以下函數接收工作候選人的姓名,並保存在JobResume列中:

  CREATE FUNCTION hr.FullName (@name XML)

  
RETURNS NVARCHAR(60) AS

  
BEGIN

  
RETURN @name.value('declare namespace ns=

  "http://schemas.microsoft.com/sqlserver/2004/07/adventure-

  works/Resume";

  concat((/ns:Resume/ns:Name/ns:Name.First)[1], " ",

  (/ns:Resume/ns:Name/ns:Name.Last)[1])
','nvarchar(60)')

  
END

  正如你所看到的,函數FullName帶一個輸入參數,該參數被定義成XML類型。這個做法是當調用此函數時,可以把包含所需提取的數據的XML列名稱作爲輸入值來使用。

  Value()方法帶兩個參數。第一個參數定義了目標XML列使用的名稱空間,第二個參數包含接收實際數據的Xquery表達式。在這個例子中,表達式使用concat()方法來連接姓與名,就像它們在XML文件中。要想了解更多的關於如何使用value()方法,以及如何創建Xquery表達式,請查看我的文章《Retrieve XML data values with XQuery》。 一旦創建了函數,你可以通過從hr.CandidateNames表的JobResume列中接收數據測試:

  SELECT CandidateID, hr.FullName(JobResume) AS FullName FROM hr.CandidateNames

   正如你所看到的,我已經傳入了XML列名稱,將其做爲函數FullName的一個參數。SELECT語句應該返回以下結果:

  注意,以上結果包含姓與名,正如它們在XML列中顯示的一樣。如果回到函數定義,可發現在value()方法中使用的Xquery表達式指定了此表達式返回值爲NVARCHAR(60)類型,以適應Unicode字符,如查詢結果集的最後三行中的那些字符。

  一旦函數經過測試,你就可以開始創建計算列:以下ALTER TABLE語句添加了FullName列到CandidateNames表中來:

  ALTER TABLE hr.CandidateNames

  
ADD FullName AS hr.FullName(JobResume)

  我已經在計算列表達式中使用FullName函數,並將列JobResume作爲參數傳入函數。在運行ALTER TABLE語句後,你可以用以下SELECT語句測試數據是否已經被插入到計算列中:

  SELECT CandidateID, FullName FROM hr.CandidateNames

  運行以上語句後,應該返回與上文中相同的結果集。

  這就是在SQL Server中基於XML data數據創建的一個計算列。關鍵是創建一個函數來運行Xquery表達式,且稍後在計算列中使用此函數定義。要了解更多關於計算列、XML列、Xquery表達式的詳細信息,請查看Microsoft SQL Server在線書籍。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章