Как объединить после вставки вместо вставки триггера? - PullRequest
1 голос
/ 12 февраля 2012

У меня есть вместо триггера обновления, который оценивает состояние до запуска, и в конце триггера я бы хотел запустить триггер после обновления, который выполняет простой запрос.Однако я не уверен, что триггер после является правильным решением, и, в любом случае, моя неуклюжая попытка включить триггер после в конце приводит к многочисленным синтаксическим ошибкам.

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

Аарон прав, этотне будет обрабатывать ситуации обновления, когда пользователь изменяет столбец xy и / или использует ГИС-приложение для перемещения точки, ОДНАКО, по крайней мере, он не падает, когда возникает такая ситуация.Я предполагал, что триггер после обновления справится с этим, но на этом этапе менеджер приложений должен следить за изменениями редких точек после их вставки.Если пользователь предоставил X или Y, является нулевым, то геометрия будет нулевой, и периодическое обслуживание БД отбросит эти записи и переместит их во временную таблицу, где местоположение находится где-то в Атлантике, для ручного определения местоположения.

Ответы [ 2 ]

2 голосов
/ 12 февраля 2012

Я понимаю, что дал вам условный код для 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_coord заполняется y, это не так (или наоборот).

1 голос
/ 12 февраля 2012

Почему бы не включить весь скрипт в триггер 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...