插入后如何组合而不是插入触发器?

时间:2012-02-12 15:41:21

标签: sql sql-server-2008

我有一个而不是更新触发器,它在触发前评估条件,并且在触发器结束时,我想触发执行简单查询的更新后触发器。但是,我不确定后触发器是否是正确的解决方案,并且,无论如何,我在最后包含后触发器的笨拙尝试会导致许多语法错误。

INSTEAD OF INSERT 
AS 
BEGIN 
IF EXISTS (SELECT 1 FROM inserted WHERE SHAPE IS NOT NULL) 
BEGIN 
INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid, loc_name) 
SELECT SHAPE, X_Coord = SHAPE.STX,Y_Coord = SHAPE.STY,objectid, loc_name 
FROM inserted; 
END

ELSE 
BEGIN 
INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid,loc_name) 
SELECT SHAPE=Geometry::STPointFromText('POINT('
+ CAST(X_Coord AS VARCHAR(20)) + ' ' 
+ CAST(Y_Coord AS VARCHAR(20)) + ')', 26917),
X_Coord, Y_Coord,objectid,loc_name
FROM inserted;
END

END
go

after insert 
as 
begin
set nocount on;
    INSERT INTO TBL_LOCATIONS (TOPO_NAME) 
    SELECT dbo.QD24K_GRSM.NAME 
    FROM   INSERTED I 
    LEFT JOIN dbo.QD24K_GRSM 
    on QD24K_GRSM.Shape.STContains(I.SHAPE) = 1;
    go

接受的答案,经过修改以处理其他案件,我确信我不是唯一可以从这个例子中受益的人:

INSTEAD OF INSERT  
AS  
BEGIN  
  SET NOCOUNT ON; 
 --insert binary xy to geo column when user enters location from non-gis app (a);
 --insert topo quad (b) name and county (c) name admin boundary which location occurs
  INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid, loc_name, TOPO_NAME, County)  
  SELECT a.Shape, a.X_Coord, a.Y_Coord, a.objectid, a.loc_name, b.NAME, c.name
  FROM 
  ( 
    SELECT 
    --see if GIS populated geo column, if not, write user-input xy to geometry 
      SHAPE = CASE WHEN SHAPE IS NOT NULL  
        THEN SHAPE ELSE Geometry::STPointFromText('POINT(' 
          + CAST(X_Coord AS VARCHAR(20)) + ' '  
          + CAST(Y_Coord AS VARCHAR(20)) + ')', 26917) END, 
    --if record was created with GIS, then translate binary to human-readable xy
      X_Coord = CASE WHEN SHAPE IS NULL THEN X_Coord ELSE SHAPE.STX END, 
      Y_Coord = CASE WHEN SHAPE IS NULL THEN Y_Coord ELSE SHAPE.STY END, 
      objectid,  
      loc_name 
    FROM inserted 
  ) AS a
  --spatial query, what topo quad is this point in?
 LEFT OUTER JOIN dbo.QD24K_GRSM AS b 
      ON b.Shape.STContains(a.Shape) = 1 
   --spatial query, what county is this point in?
  LEFT OUTER JOIN dbo.COUNTY as c 
      ON c.Shape.STContains(a.Shape) = 1; 
END 
GO 
GO

Aaron是对的,这不会处理用户改变xy列和/或使用GIS应用程序移动点的更新情况,但是,当发生这种情况时,至少它不会崩溃。我认为更新后的触发器会处理它,但在此阶段,应用程序管理器的角色是在插入后跟踪罕见的点编辑。如果用户提供的X或Y为null,则几何将为null,并且定期DB维护将剔除这些记录,并将它们移动到位于大西洋某处的临时表,以进行手动位置确定。

2 个答案:

答案 0 :(得分:2)

我意识到我给了你IF EXISTS的条件代码但是在进一步思考时我不认为这是必要的。一旦你计算了尚未提供的形状,你仍然可以在一个声明中完成所有这些工作。

CREATE TRIGGER dbo.mytrigger
ON dbo.TBL_Locations
INSTEAD OF INSERT 
AS 
BEGIN 
  SET NOCOUNT ON;

  INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid, loc_name, TOPO_NAME) 
  SELECT d.Shape, d.X_Coord, d.Y_Coord, d.objectid, d.loc_name, g.NAME
  FROM
  (
    SELECT 
      SHAPE = CASE WHEN SHAPE IS NOT NULL 
        THEN SHAPE ELSE Geometry::STPointFromText('POINT('
          + CAST(X_Coord AS VARCHAR(20)) + ' ' 
          + CAST(Y_Coord AS VARCHAR(20)) + ')', 26917) END,
      X_Coord = CASE WHEN SHAPE IS NULL THEN X_Coord ELSE SHAPE.STX END,
      Y_Coord = CASE WHEN SHAPE IS NULL THEN Y_Coord ELSE SHAPE.STY END,
      objectid, 
      loc_name
    FROM inserted
  ) AS d
  LEFT OUTER JOIN dbo.QD24K_GRSM AS g
      ON g.Shape.STContains(d.Shape) = 1;
END
GO

既不是现有的解决方案,也不是处理奇怪的情况,例如当形状和x / y坐标全部填充时,或者当所有三个值都为空时,或者当x填充x时没有(或反之亦然)

答案 1 :(得分:1)

为什么不在INSTEAD OF INSERT触发器中包含所有脚本?

INSTEAD OF INSERT 
AS 
BEGIN 
  IF EXISTS (SELECT 1 FROM inserted WHERE SHAPE IS NOT NULL)     
  BEGIN         
    INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid, loc_name)             
    SELECT SHAPE, X_Coord = SHAPE.STX,Y_Coord = SHAPE.STY,objectid, loc_name            
    FROM inserted;    
  END
  ELSE     
  BEGIN 
    INSERT dbo.TBL_Locations(SHAPE, X_Coord, Y_Coord,objectid,loc_name)             
    SELECT SHAPE=Geometry::STPointFromText('POINT('+ CAST(X_Coord AS VARCHAR(20)) + ' ' + CAST(Y_Coord AS VARCHAR(20)) + ')', 26917), X_Coord, Y_Coord,objectid,loc_name
    FROM inserted;
  END

  set nocount on;

  INSERT INTO TBL_LOCATIONS (TOPO_NAME)        
  SELECT dbo.QD24K_GRSM.NAME        
  FROM   INSERTED I               
  LEFT JOIN dbo.QD24K_GRSM                 
  on QD24K_GRSM.Shape.STContains(I.SHAPE) = 1;
END
go