2009-10-20 79 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