Sql Server 2008触发器

0 sql-server sql-server-2008

Message已经有一个触发器.在触发器内成功运行我有一个insert声明:

Insert into tblSettlement (MessageID,Lat,Long) Select Messageid,y,x from inserted
Run Code Online (Sandbox Code Playgroud)

在桌子上tblSettlement我放置了触发器:

 ALTER TRIGGER [dbo].[AddSettlementOnINSERT]
 ON [dbo].[TblSettlement]
 After INSERT
  AS
 DECLARE @id Bigint, @Lat Float,@Long Float, @LocName Varchar(200), @Dist float,@upd    bit 
 Set @upd = (SELECT updated FROM inserted)
 SET @id = (SELECT MessageID FROM inserted)
SET @lat = (SELECT [Lat] FROM inserted)
SET @Long = (SELECT [Long] FROM inserted)
if (@upd = 0) 
begin
declare @table table 
(Location Varchar(200),Distance float)
insert into @table 
SELECT  top 1 Full_Name_nd, SQRT(
  POWer(69.1 * (lat - @lat), 2) +
   POWer(69.1 * (@long - long) * COS(lat / 57.3), 2))As distance
 FROM geodb.dbo.geonames where SQRT(
  POWer(69.1 * (lat - @Lat), 2) +
  POWer(69.1 * (@Long - long) * COS(lat / 57.3), 2)) < 1 
 set @LocName = (select location from @table)
 set @Dist = (select distance from @table)
 Insert into dbo.tblset2

 (Messageid,lat,long,settlement,distance)values(@id,@lat,@long,@locName,@Dist)
  end
Run Code Online (Sandbox Code Playgroud)

但问题是,每当我们启用上面的触发器时,插入就会停止在Message表上工作.

含义:我们希望在插入后插入几个列值并尝试在同一个表的触发器中更新另一个表.这实际上不允许我们插入.

mar*_*c_s 5

关于SQL Server触发器的基本假设是错误的 - 您似乎假设(正如许多人所做的那样)每插入一次将触发一次触发器 - 事实并非如此!

触发器将在每个语句中调用一次 - 也就是说,如果您的语句一次插入20行,则触发器将被调用一次,伪表Inserted将包含20行.

因此,如果Inserted包含多行,则此处的语句将失败,或者选择任意随机条目:

DECLARE @id Bigint, @Lat Float,@Long Float, @LocName Varchar(200), @Dist float,@upd    bit 
Set @upd = (SELECT updated FROM inserted)
SET @id = (SELECT MessageID FROM inserted)
SET @lat = (SELECT [Lat] FROM inserted)
SET @Long = (SELECT [Long] FROM inserted)
Run Code Online (Sandbox Code Playgroud)

你必须完全重写你的触发器,考虑到Inserted可以并且将包含多行.

  • 将标量变量设置为插入或删除的字段是错误写入触发器的可靠信号. (2认同)