0
我有一個非常通用的一套存儲所有的數據,其工作出色的三個表(我們所說的少量數據在這裏)SQL服務器:遞歸存儲過程
DataContainer - 管理「記錄」
PK - DataContainerId
FK - ParentDataContainerId
FM - ModelEntityId
DataInstance - 管理版本
PK - DataInstanceId
FK - DataContainerId
IsCurrent [bit] NOT NULL CONSTRAINT [DF_DataInstance_IsCurrent] DEFAULT ((1)),
ModifiedBy [nvarchar](50) NOT NULL CONSTRAINT [DF_DataInstance_ModifiedBy] DEFAULT (suser_sname()),
ModifiedDateTime [datetime] NOT NULL CONSTRAINT [DF_DataInstance_ModifiedDateTime] DEFAULT (getdate()),
DataValue
PK - DataValueId
FK - DataInstanceId
FK - ModelEntityId
ValueText --the actual values
問題:當一條記錄被刪除,我需要標記爲刪除所有子記錄。
嘗試
--flag current record as deleted
update DataInstance
set IsCurrent = 0
Where DataContainerId = @DataContainerId
And (@ModelContainerId is null or @ModelContainerId = ModelContainerId)
--remove all child records
declare db_cursor for
select sc.DataContainerId as 'ChildDataContainerId' from DataInstance di
inner join datacontainer dc on dc.datacontainerId = di.datacontainerId
where parentdatacontainerId = @DataContainerId
declare @ChildDataContainerId int
open db_cursor
fetch next from db_cursor into @ChildDataContainerId
while @@fetch_status = 0
begin
exec dataInstance_Delete null, @ChildDataContainerId --current sp
end
close db_cursor
deallocate db_cursor
的問題是,我不能使用遊標recursivly(因爲我得到一個錯誤,光標已經打開),所以這個SP只會工作一個級別深度。
有沒有更狡猾的做法呢?
存儲所有的數據在一個表中,然後使用遊標來處理你的記錄,你應該從脫身的做法。當你忽略規範化數據的智慧以及SQL設計的設置邏輯的力量時,你就會頭痛不已。也許你應該考慮爲了自己的利益重構以後的重構? – Tahbaza 2010-06-30 03:45:38
由於我討厭貼在泥土中,只是發表負面評論,然後走開這裏,如果您決定繼續前進,則可以解決您的問題:使用SQL以外的應用程序編程語言進行遞歸。它們通常不受遞歸調用規則的限制,如果您更喜歡行邏輯,則可以使用記錄集或同等方法更輕鬆地處理記錄。快樂的編碼... – Tahbaza 2010-06-30 03:49:19
我不得不同意Tahbaza,但如果你堅持採取這條路線,我會使用觸發器。觸發器可以遞歸執行(達到某個(可配置的我相信)級別)。 – 2010-06-30 08:01:30