编写复杂的触发器

时间:2009-10-20 20:42:58

标签: sql sql-server tsql sql-server-2000

我正在使用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,LastName,FirstName,Date,Time,Company,Location Number,Location Name,StatusDisposition,User)

我的问题是内部联接的查询...

1 个答案:

答案 0 :(得分: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更改为删除或插入。

你会注意到我在临时表中有两条记录,其中一条符合你的条件,其中一条没有。这允许您测试多个记录更新以及满足条件的结果和不满足条件的结果。应编写所有触发器以处理多个记录,因为它们不是逐行而是按批处理。