2012-02-11 12 views
0

私は2つの列は、いくつかの異なるアプリケーションから移入することができるアプリケーションがあります。 1つはXY位置(ステゲトリー)はアプリケーションによって決定されます.2つは、XY位置はユーザーによって別々のxとyの列にタイプされます。トリガーの代わりに動作しません

シナリオ1のX列とY列にデータを入力し、シナリオ2で図形列に入力するためのトリガを考えました。ループしていて、どちらの列も入力していないようです。どこで私は間違えましたか?

ALTER trigger [dbo].[update_location_geometry] 
    --Trigger to allow non-gis input of XY data in X_Coord and Y_Coord columns, yet still populate the WKB 
    --shape column with coordinate using 26917 EPSG so that new location will be available to the gis without 
    -- additional user intervention 
    on [dbo].[TBL_LOCATIONS] 
    instead of insert as -- Aaron changed update to insert here 


IF UPDATE(X_Coord) OR UPDATE(Y_Coord) 

Begin 
update dbo.tbl_locations 
set SHAPE=Geometry::STPointFromText('POINT(' + CAST(X_Coord AS VARCHAR(20)) + ' ' + 
CAST(Y_Coord AS VARCHAR(20)) + ')', 26917) 

END 
IF UPDATE(Shape) 
Begin 
update dbo.tbl_locations 
set X_Coord = SHAPE.STX,Y_Coord = SHAPE.STY 

End 

そして、これは構文エラー生成します:

instead of update as 

IF update (X_Coord) OR UPDATE(Y_Coord) AND objectId IN (SELECT ins.objectId FROM inserted ins) 

Begin 
update dbo.tbl_locations 
set SHAPE=Geometry::STPointFromText('POINT(' + CAST(X_Coord AS VARCHAR(20)) + ' ' + 
CAST(Y_Coord AS VARCHAR(20)) + ')', 26917) 

END 
IF UPDATE(Shape)AND objectId IN (SELECT ins.objectId FROM inserted ins) 
Begin 
update dbo.tbl_locations 
set X_Coord = SHAPE.STX,Y_Coord = SHAPE.STY 

End 


Msg 207, Level 16, State 1, Procedure update_location_geometry, Line 10 
Invalid column name 'objectId'. 
Msg 207, Level 16, State 1, Procedure update_location_geometry, Line 18 
Invalid column name 'objectId'. 

最終解決:インサートの

ALTER TRIGGER [dbo].[update_location_geometry] ON [dbo].[TBL_LOCATIONS] 
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 

例:

ALTER trigger [dbo].[update_location_geometry] 
    --Trigger to allow non-gis input of XY data in X_Coord and Y_Coord columns, yet still populate the WKB 
    --shape column with coordinate using 26917 EPSG so that new location will be available to the gis without 
    -- additional user intervention 
    on [dbo].[TBL_LOCATIONS] 
    instead of insert as 
    begin 
--this block populates stgeometry.shape col with user-input XY and is not using the application to 
-- determine xy 
    if exists (select top 1 * from inserted where shape is not null) 

    update dbo.tbl_locations 
    set SHAPE=Geometry::STPointFromText('POINT(' + CAST(X_Coord AS VARCHAR(20)) + ' ' + 
         CAST(Y_Coord AS VARCHAR(20)) + ')', 26917) 
    WHERE (UPDATE(X_Coord) OR UPDATE(Y_Coord)) 
       AND objectId IN (SELECT ins.objectId FROM inserted ins) 


    --this block populates the XY column from stgeometry.shape when the application calculated XY 
    update dbo.tbl_locations 
    set X_Coord = SHAPE.STX,Y_Coord = SHAPE.STY 
    WHERE (UPDATE(Shape)) 
       AND objectId IN (SELECT ins.objectId FROM inserted ins) 
    End 

はまだループし、同様にこれを試してみました

INSERT INTO [ATBI].[dbo].[TBL_LOCATIONS] 
      ([OBJECTID] 
      ,[X_Coord] 
      ,[Y_Coord] 
      ,Loc_Name, 
      Notes) 

    VALUES 
      (368 
      ,324999.997 
      ,3970798.079 
      ,'blahblah' 
      ,'notes of test') 

生産テーブル:挿入トリガーで

CREATE TABLE [dbo].[TBL_LOCATIONS](
    [OBJECTID] [int] NOT NULL, 
    [FCategory] [nvarchar](16) NULL, 
    [MapMethod] [nvarchar](4) NULL, 
    [HError] [nvarchar](50) NULL, 
    [MapSource] [nvarchar](255) NULL, 
    [SourceDate] [datetime2](7) NULL, 
    [EditDate] [datetime2](7) NULL, 
    [Notes] [nvarchar](255) NULL, 
    [Site_ID] [uniqueidentifier] NULL, 
    [Meta_MID] [nvarchar](50) NULL, 
    [X_Coord] [numeric](38, 8) NULL, 
    [Y_Coord] [numeric](38, 8) NULL, 
    [Coord_Units] [nvarchar](50) NULL, 
    [Coord_System] [nvarchar](50) NULL, 
    [UTM_Zone] [nvarchar](50) NULL, 
    [Accuracy_Notes] [nvarchar](max) NULL, 
    [Unit_Code] [nvarchar](12) NULL, 
    [Loc_Name] [nvarchar](100) NULL, 
    [Loc_Type] [nvarchar](25) NULL, 
    [Updated_Date] [nvarchar](50) NULL, 
    [Loc_Notes] [nvarchar](max) NULL, 
    [Datum] [nvarchar](5) NULL, 
    [Watershed] [nvarchar](50) NULL, 
    [StreamName] [nvarchar](50) NULL, 
    [NHDReachCode] [nvarchar](14) NULL, 
    [TOPO_NAME] [nvarchar](50) NULL, 
    [Trail] [nvarchar](100) NULL, 
    [Road] [nvarchar](50) NULL, 
    [Elevation] [numeric](38, 8) NULL, 
    [LAT] [numeric](38, 8) NULL, 
    [LON] [numeric](38, 8) NULL, 
    [Year_] [nvarchar](4) NULL, 
    [County] [nvarchar](30) NULL, 
    [State] [nvarchar](30) NULL, 
    [IsExtant] [nvarchar](3) NULL, 
    [IsSenstive] [nvarchar](3) NULL, 
    [Eco_Notes] [nvarchar](50) NULL, 
    [EcoGroup] [nvarchar](50) NULL, 
    [ELCode] [smallint] NULL, 
    [Validation] [nvarchar](50) NULL, 
    [LocationDescription] [nvarchar](max) NULL, 
    [LocationDirections] [nvarchar](max) NULL, 
    [VerbatimLocation] [nvarchar](255) NULL, 
    [PlaceName] [nvarchar](75) NULL, 
    [SHAPE] [geometry] NULL, 
    [Location_ID] [uniqueidentifier] NOT NULL, 
CONSTRAINT [PK_TBL_LOCATIONS] PRIMARY KEY CLUSTERED 
(
    [OBJECTID] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] 

GO 

ALTER TABLE [dbo].[TBL_LOCATIONS] WITH CHECK ADD CONSTRAINT [g2_ck] CHECK (([SHAPE].[STSrid]=(26917))) 
GO 

ALTER TABLE [dbo].[TBL_LOCATIONS] CHECK CONSTRAINT [g2_ck] 
GO 

ALTER TABLE [dbo].[TBL_LOCATIONS] ADD CONSTRAINT [DF__TBL_LOCAT__Globa__12C8C788] DEFAULT (newsequentialid()) FOR [Location_ID] 
GO 
+1

2番目の試行でテーブル全体が更新されました。挿入されたテーブルとの相関はまったくありません。あなたのテーブルが空でない限り(それ以外の場合はテーブル全体が更新されていることに気づくでしょう)、私は再び 'UPDATE'ステートメントを実行中で、このトリガーは' INSERT'トリガーのため起動していない可能性があります。 –

答えて

3

は、UPDATEメイクセンスをチェックするのですか? INSTEAD OF INSERTの代わりにINSTEAD OF UPDATEトリガーにすることを意味しましたか? [OK]を

IF UPDATE(X_Coord) OR UPDATE(Y_Coord) 
BEGIN 
    -- first update without first where clause 
END 

IF UPDATE(Shape) 
BEGIN 
    -- second update without first where clause 
END 

私はあなたの代わりに使用しようとしていたという事実に貼り付けたので:WHERE句とは対照的に、また

、それはUPDATEトリガする必要がありますと仮定すると、私は通常、このようにチェックします更新の挿入トリガーの問題は、トリガーの代わりにの代わりにが実行されているため、トリガーの代わりに自分で挿入操作を実行する必要があることです。 (、あなたにもinsertedからそれらをプルする必要があります他の列がある場合はSHAPEまたはX_Coord/Y_Coordと一緒に挿入されることに注意)、これを試してみてください:

CREATE TRIGGER [dbo].[update_location_geometry] 
ON [dbo].[TBL_LOCATIONS] 
INSTEAD OF INSERT 
AS 
BEGIN 
    INSERT dbo.TBL_Locations(ObjectID, SHAPE, X_Coord, Y_Coord) 
     SELECT ObjectID, SHAPE, X_Coord = SHAPE.STX, Y_Coord = SHAPE.STY 
     FROM inserted WHERE SHAPE IS NOT NULL; 

    INSERT dbo.TBL_Locations(ObjectID, SHAPE, X_Coord, Y_Coord) 
     SELECT ObjectID, SHAPE=Geometry::STPointFromText('POINT(' 
      + CAST(X_Coord AS VARCHAR(20)) + ' ' 
      + CAST(Y_Coord AS VARCHAR(20)) + ')', 26917), 
      X_Coord, Y_Coord 
     FROM inserted WHERE SHAPE IS NULL; 
END 
GO 

を私は次のINSERT文と彼らでこれを試してみました

INSERT dbo.TBL_Locations(ObjectID, X_Coord, Y_Coord) 
    SELECT 1, 20, 30; 

INSERT dbo.TBL_Locations(ObjectID, Shape) 
    SELECT 2, 0x25690000010C00000000000034400000000000003E30; 
+0

「AND objectId IN(SELECT ins.objectId FROM inserted ins)」を追加するとエラーが発生します。私は間違いなくここで非常に明白な構文が欠けています。これを何時間も見つめていた。この特定の状況におけるデータのソースは常に挿入されます。 – tpcolson

+0

はい、正しいです。他の列が挿入時にユーザーまたはアプリケーションによって作成されている場合、トリガーが存在しないため、その列が失敗します。トリガ内のすべての列をグローバルに含めることは、パフォーマンス面で面倒すぎるでしょうか?ユーザーは、編集時に他のものの一部または全部を入力する選択肢があります。また、すぐに作成されるstwithinを使用してロットを自動化するトリガー(たとえば、どの状態がポイントですか?)に役立ちます。 – tpcolson

+0

いいえ、挿入前にこれらの計算を実行する必要がある場合は、ユーザーが指定する可能性のある他の列を追加します(ただし、「失敗」の意味はわかりません)。同じことを話している)。オプションで必要な列を指定したり指定したりできない場合は、デフォルト値またはトークン値を入力するために 'COALESCE'を使用する必要があります(または、それらの列を' NULL'から 'NOT NULL'に変更してそれらを「NULL」のままにする)。代わりにAFTERトリガーを使用して更新機能だけをテストすることも考えられます。 –

関連する問題