2012-02-12 18 views
1

私は発砲する前に状態を評価する更新トリガーを持っています。トリガーの終わりに、単純な照会を実行するアフターアップデートトリガーを発射したいと思います。しかし、アフタートリガーが正しい解決策であるかどうかはわかりません。いずれにせよ、アフタートリガーを最後に含めると、多くの構文エラーが発生します。追加の例を処理するように変更答えを、受け入れ挿入トリガーの代わりに挿入後の組み合わせ方法?

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がNULLの場合、ジオメトリはNULLになり、定期的なDBメインテナンスによってレコードが削除され、手動による場所決定のために、場所が大西洋のどこかにある一時テーブルに移動されます。

+0

トリガーが壊れています。 'inserted'は複数の行を含むことができる疑似テーブルです。したがって、 'IF EXISTS'テストを実行すると、たいていは* single *行のステータスが表示されます。 –

+0

@Damienはい、 'FROM inserted'ビットには、それらの行だけを選択するための同等の' WHERE'節が必要です。私は下の私のソリューションのトリガーを、チェックを全く必要としないように更新しました。 –

答えて

2

私は私があなたにIF EXISTSのための条件付きコードを与えたが、さらなる反射に、私はそれが必要だとは思わない実現。まだ提供されていない場合にシェイプを計算したら、この作業をすべて1つのステートメントで実行できます。形状及びX/Y COORDSがすべて取り込まれたとき、または3つのすべての値がヌルであるか、またはx_coordをyによって移入されたときにない場合

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 

既存のソリューションも、これのいずれも、例えば、奇数の場合を取り扱う(あるいは逆に)。

+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

それを考えて、 'Msg 0、Level 11、State 0、Line 0を返します。 現在のコマンドで重大なエラーが発生しました。結果があれば破棄する必要があります。 – tpcolson

+0

その場合は、最後の挿入文に問題があり、トリガーに置かれている場所とは何の関係もないかもしれません。それがうまくいけば、その文は、TOPO_NAMEフィールドにのみ値を持つ2番目のレコードをTBL_Locationsに挿入します。それは意図ですか? – Paul

+0

いいえ。個別に、それぞれのトリガは、もう一方のトリガがオフのときに機能します。ユーザーが[X_Coord]と[Y_Coord]を入力した場合、または[Shape]列が入力されている場合は[X_Coord]列と[Y_Coord]列にデータを入力すると、最初のトリガーが[shape]列にデータを格納します。 2番目のトリガは、空間クエリを実行し、結果(ポリポイントの名前が入っている)を[topo_name]カラムに書き込むものとします。これはすべて一列に起こるはずです。例えば。ユーザは新しい行を入力し、その行にXYが計算され、その行に対してトポの名前が決定されます。 – tpcolson

関連する問題