來說說數據庫自定義函數的遞歸用法如:C18 數碼攝像機 是在 C12 數碼產品 類別下
而 C12 數碼產品 又在C2 IT產品 類別下!
C2 IT產品 在 000(根節點下)
即分類為 C2 IT產品-C12 數碼產品-C18 數碼攝像機
現在假使有這樣一種需要 ,通過
SQLserver平台,達到給定ClassID得到其所有父節點的ClassID,並且通過“_”連接起來!如 C18 的結果為 C2_C12_C18 如下表
可以看到 數碼攝像機的Place字段為 C2_C12_C18,字段Place為標識字段,需求中有一定的作用!
這樣,當我們添加一個分類時,除了指定基本信息外,還需要指定其Place,才可以順利添加一條記錄!
當時可以通過很多方法得到新添加記錄的Place,但假使現在的需求是通過SQL自定義遞歸函數來完成功能!
如何實現?給定ClassID(該數據可以通過添加時得到的@@identity 全局變量獲取) 得到Place!
看如下SQL語句 -------------------------------------------
項目:公司Cmwin產品庫
名稱: F_ContactAllParentPlaceByClassID
功能: 通過classID生成其Place 前綴。除自己的Place
鏈接其所有父ClassID
相關表:ClassTree_update 時間:2007-11-22 11:22 -------------------------------------------
*/
CREATE function F_ContactAllParentPlaceByClassID @classID varchar(15) --參數
)
returns varchar(500)
as
begindeclare @ParentClassID varchar(15) --變量父ID
declare @Place varchar(500) --變量Place
set @Place = ''
--首先根據傳入的ClassID獲取其父ID,ParentClassID
SELECT @ParentClassID = ParentClassID FROM ClassTree_update
where ClassID = @classID
/**//*到此,我們得到 其父ID 例如 C18 我們可以得到 C12 但問題還沒有完,
C12本身也還有父節點,即C2。我們還需要將C2取出,C2的父節點為000即為根節點。 因此,由此問題可以看出,這是一個遞歸過程,根據指定ClassID獲取其父ID。再
根據父ID繼續獲取父ID的父ID,一直遞歸,直至父ID為000為止!
因此下面實現SQL函數的遞歸 ,注意看
*/
if (@ParentClassID <> '000')--如果不是根節點
begin
-- 再將@ParentClassID父ID作為ClassID傳入 進行自調用
set @Place = dbo.F_ContactAllParentPlaceByClassID(@ParentClassID) + @ParentClassID+'_'
end
return @Place
end 已有詳細說明!運行看
留心一下,有的SQL版本運行上述SQL語句在dbo.F_ContactAllParentPlaceByClassID(@ParentClassID)會報錯。原因是,此時正的創建dbo.F_ContactAllParentPlaceByClassID函數,而還未創建,在又在此處調用dbo.F_ContactAllParentPlaceByClassID(@ParentClassID),因此會提示沒有這個對象,解決辦法是先去掉dbo.F_ContactAllParentPlaceByClassID(@ParentClassID)創建後再Alter修改 即可!我遇見過一次!運行效果
給定'C18'即得到其所有父節點的Place 並且使用"_"鏈接起來,離要求已經很近了,只是最後再將C18連在其後就達到要求,C18又是已知的!ClassID字段為遞增,在實際添加分類時可以通過@@identity變量獲取到!連在其後即是 C2_C12_C18_
至此,通過SQL自定義函數實現給定ClassID 拼截出其對應的Place標識符!總結:這裡只是演示一下SQL自定義函數的用法,並且實現一個簡單的遞歸。當然,要實現這個功能,不一定要使用函數。我在此只是作為演示函數用法而講講!有時使用SQL函數還是很方便的!