2009-10-20 114 views
0

我使用SQL Server 2000中我寫被執行觸發器時現場Applicant.AppStatusRowID編寫複雜的觸發

表申請人鏈接到表的位置,表公司&表其appStatus。

我的問題是在我的查詢中創建連接。

當Applicant.AppStatusRowID更新,我想從 Applicant.AppStatusRowID,Applicant.FirstName,Applicant.Lastname,Location.LocNumber,Location.LocationName,Company.CompanyCode獲取值,AppStatus.DisplayText

這些連接將是:

Select * from Applicant A 
Inner Join AppStatus ast on ast.RowID = a.AppStatusRowID 
Inner Join Location l on l.RowID = a.LocationRowID 
Inner Join Company c on c.RowID = l.CompanyRowID 

這是要插入到審覈表(字段ApplicantID,姓氏,名字,日期,時間,公司,地點數量,位置名稱,StatusDisposition,用戶)

我的問題是查詢內部連接...

+0

我希望你沒有更新主鍵,這是一個壞主意。 – 2009-10-20 20:51:16

+0

如果您更新密鑰,您如何加入其他表? _ast.RowID = a.AppStatusRowID_ – 2009-10-20 21:03:59

回答

3

首先讓我們介紹一下插入和刪除的只能在觸發器中使用的僞指令。插入有新值,並刪除舊值或記錄被刪除。

您不希望將所有記錄插入到您的審計表中,只有那些插入的記錄。

所以插入到審計表中,你可能要像觸發器裏面的代碼:

insert Myaudittable (<insert field list here>) 
Select <insert field list here> from Inserted i 
Inner Join AppStatus ast on ast.RowID = i.AppStatusRowID 
Inner Join Location l on l.RowID = i.LocationRowID 
Inner Join Company c on c.RowID = l.CompanyRowID 

我會親自加列新老值,變化的類型和什麼樣的日期一欄的變化以及用戶做出了哪些變更,但您肯定有自己的要求要遵循。

建議您閱讀有關圖書在線的觸發器,因爲它們可能會很棘手以便正確使用。

以下是我經常使用的測試和調試觸發器的一種方法。首先,我創建臨時表名稱#delted和#inserted,這些名稱具有我要將觸發器放在表格中的結構。然後我編寫代碼來使用這些代碼,而不是刪除或插入的表格。在我將代碼更改爲觸發器之前,我可以隨時看看事情並確保一切正常。例如下面與您在代碼中添加和略作修改:

Create table #inserted(Rowid int, lastname varchar(100), firstname varchar(100), appstatusRowid int) 
    Insert #inserted 
    select 1, 'Jones', 'Ed', 30 
    union all 
    select 2, 'Smith', 'Betty', 20 

    Create table #deleted (Rowid int, lastname varchar(100), firstname varchar(100), appstatusRowid int) 
    Insert #deleted 
    select 1, 'Jones', 'Ed', 10 
    union all 
    select 2, 'Smith', 'Betty', 20 

--CREATE TRIGGER tri_UpdateAppDisp ON dbo.Test_App 
--For Update 
--AS 
--If Update(appstatusrowid) 
IF exists (select i.appstatusRowid from #inserted i join #deleted d on i.rowid = d.rowid 
      Where d.appstatusrowid <> i.appstatusrowid) 
BEGIN 
--Insert AppDisp(AppID, LastName, FirstName, [DateTime],Company,Location,LocationName, StatusDisp,[Username]) 
Select d.Rowid,d.LastName, d.FirstName, getDate(),C.CompanyCode, 
l.locnum,l.locname, ast.Displaytext, SUSER_SNAME()+' '+User 
From #deleted d 
Join #inserted i on i.rowid = d.rowid 
--From deleted d 
--Join inserted i on i.rowid = d.rowid 
Inner join Test_App a with (nolock) on a.RowID = d.rowid 
inner join location l with (nolock) on l.rowid = d.Locationrowid 
inner join appstatus ast with (nolock) on ast.rowid = d.appstatusrowid 
inner join company c with (nolock) on c.rowid = l.CompanyRowid 
Where d.appstatusrowid <> i.appstatusrowid) 
end 

一旦你獲得了數據的選擇是正確的,那麼很容易取消註釋出觸發代碼和插件線,並更改#DELETED或#inserted到刪除或插入。

你會注意到我在臨時表中有兩條記錄,其中一條符合你的條件,其中一條沒有。這允許您測試多條記錄更新以及滿足條件的結果以及不滿足條件的結果。應該寫入所有觸發器來處理多個記錄,因爲它們不是逐行而是逐批地觸發的。

+0

不幸的是我受限於我能獲得的創造力。一旦有人更新申請人表中的AppStatusRowID,我需要將記錄插入到審計表中。因此需要觸發器。但我無法讓我的連接查詢工作。 – DotNetRookie 2009-10-20 20:58:04

+0

然後,您可能必須使用AppStatusRowID的舊值,即引用DELETED(而不是上面的代碼中的Inserted)。 – Thorsten 2009-10-20 21:02:57

+0

我試過DELETED,但仍然沒有爲我工作。目標表未更新。 – DotNetRookie 2009-10-20 21:30:43