超強存儲過程

 在開發數據庫應用程序中,我們經常需要表示多層次關係的數據,譬如:MRP中的BOM,多級別的組織結構,多級的角色關係…… 在數據庫中描述這種關係時,我們通常使用父節點指向的方式來設計表結構,譬如對部門的表結構定義如下:

  CREATE TABLE TDepartment
  (
    ParentNo varchar(25),    /* 上級部門編號,如果爲NULL則表示當前記錄爲頂級部門。 */
    DepartmentNo varchar(25) PRIMARY KEY CLUSTERED/* 當前部門編號,主關鍵字段。 */
    Name  nvarchar(100) NOT NULL,   /* 部門名稱。 */
    NameEx  nvarchar(100),    /* 擴展名稱。 */
    Remark  nvarchar(500)    /* 備  注。 */
  )

  功能需求:獲取指定部門編號及其所屬的所有或指定層次的下級部門的記錄集。

  在以往的開發中,我們通常是在客戶端或者中間層來處理以上需求的,一般是通過編程語言(VB、Delphi、Java/.NET)來處理從數據庫返回的記錄集,這種方式通常需要從數據庫獲得整個表的記錄,因爲我們不能確定給定主鍵所具有的哪些下級記錄,然後再在編程代碼中使用遞歸的方式來獲取相關的下級記錄。這種使用遞歸的方式,通常難以避免數據中非法記錄所引起的死循環問題(當然,你也可以處理這種問題,只是有些麻煩,而且通常也不夠優美)。那麼,能不能在數據庫中就處理好這個問題呢,這樣既能減少不必要的數據傳輸,又能避免使用遞歸所帶來的負面影響,最好還能自動屏蔽掉非法數據指向的問題(當前記錄的父指針字段指向其某個下級記錄)。
  呵呵,賣弄完畢,亮出匕首(代碼,Transact-SQL/MS-SQLServer 2000):

/* Copyright all(c) 2004 ZhongFeng, http://blog.csdn.net/SW515 */
CREATE PROCEDURE dbo.PSelectDepartmentHierarchy
  @DepartmentNo    varchar(25),
  @Depth           int  = -1
AS
  SET NOCOUNT ON

  DECLARE @TStack TABLE
  (
    Indicator varchar(50)
  )

  DECLARE @Index int
  SET @Index = 0

  INSERT INTO @TStack
    SELECT DepartmentNo
    FROM dbo.TDepartment
    WHERE DepartmentNo LIKE @DepartmentNo

  WHILE @@ROWCOUNT > 0 AND (@Index < @Depth OR @Depth < 0)
  BEGIN
    SET @Index = @Index + 1

    INSERT INTO @TStack
      SELECT DepartmentNo
      FROM dbo.TDepartment
      WHERE
        ParentNo IN (SELECT Indicator FROM @TStack) AND
        
DepartmentNo NOT IN (SELECT Indicator FROM @TStack)
  END

  SELECT dbo.TDepartment.*
  FROM @TStack AS t
    INNER JOIN dbo.TDepartment ON
      t.Indicator = dbo.TDepartment.DepartmentNo
GO

作者Blog:http://blog.csdn.net/SW515/

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