2012-02-12 4 views
1

나는 발사하기 전에 조건을 평가하는 업데이트 트리거 대신 트리거의 끝에서 간단한 쿼리를 수행하는 업데이트 후 트리거를 시작하고 싶습니다. 그러나, after 트리거가 올바른 해결책인지 확실하지 않으며, 어쨌든 after 트리거를 끝까지 포함시키려는 시도가 너무 많아 많은 구문 오류가 발생합니다.삽입 트리거 대신 삽입 후 결합하는 방법?

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 열을 변경하거나 GIS 응용 프로그램을 사용하여 지점을 이동하는 상황 (상황에 따라 충돌이 발생하지 않음) 업데이트 후 트리거가이를 처리 할 것으로 예상되지만,이 단계에서는 삽입 된 희귀 포인트 편집 내용을 추적하는 것이 응용 프로그램 관리자의 역할입니다. 사용자가 제공 한 X 또는 Y가 널이면 Geometry는 널 (NULL)이되며주기적인 DB 유지 보수는 수동으로 위치를 판별하기 위해 해당 레코드를 추려 내고 위치가 대서양 어딘가에있는 임시 테이블로 이동시킵니다.

+0

트리거가 끊어졌습니다. 'inserted'는 여러 개의 행을 포함 할 수있는 의사 테이블입니다. 따라서'IF EXISTS' 테스트를 수행하면 대부분 단일 * 행의 상태를 알 수 있습니다. –

+0

@Damien 예, 'FROM inserted'비트에는 해당 행만 선택하는 동등한'WHERE' 절이 있어야합니다. 나는 체크를 전혀 요구하지 않기 위해 아래의 솔루션에서 방아쇠를 업데이트했다. –

답변

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 좌표 모두 채워지는 예를 들어, 홀수의 경우를 처리 또는 둘 모두 세 값은 널 (NULL) 또는 x_coord가 Y로 채워지는 경우가 없다 (혹은 때 그 반대의 경우도 마찬가지입니다.

+0

모양이 GIS로 채워지면 원하는 동작 인 사용자 xy보다 우선합니다. 다시 한 번 감사드립니다! 이제 STDistance 트리거에 .... – tpcolson

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 
+0

은 그것을 생각하고'메시지 0, 레벨 11, 상태 0, 라인 0을 반환합니다. 현재 명령에 심각한 오류가 발생했습니다. 그 결과는 버려 져야합니다. ' – tpcolson

+0

그럴 경우 트리거에 삽입 된 위치와 아무 관련이없는 마지막 insert 문에 문제가있을 수 있습니다. 작동하면,이 명령문은 TOPO_NAME 필드에만 값이있는 TBL_Locations에 두 번째 레코드를 삽입합니다. 그게 의도입니까? – Paul

+0

번호 개별적으로 각 트리거는 다른 트리거가 꺼지면 작동합니다. [X_Coord] 및 [Y_Coord]가 사용자에 의해 채워 지거나 [Shape] 열이 채워진 경우 [X_Coord] 및 [Y_Coord] 열을 채우는 경우 첫 번째 트리거가 [shape] 열을 채우게됩니다. 두 번째 트리거는 공간 쿼리를 수행하고 결과 (폴리 포인트의 이름이 발생하는)를 [topo_name] 열에 작성합니다. 이것은 모두 하나의 행에서 발생하기로되어 있습니다. 예 : 사용자가 새 행을 입력하면 해당 행에서 XY가 계산되고 해당 행에 대해 토폴 이름이 결정됩니다. – tpcolson