而不是触发器不工作

时间:2012-02-11 01:02:08

标签: sql-server-2008

我有一个应用程序,可以从许多不同的应用程序中填充两列;一,XY位置(stgeometry)由应用程序确定:二,XY位置由用户键入单独的x和y列。

我已经提出了以下触发器来填充方案一中的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
    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

也试过这个,仍然循环:

  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

插入示例:

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 个答案:

答案 0 :(得分:3)

在插入触发器中,检查UPDATE是否有意义?您的意思是将其设为INSTEAD OF UPDATE触发器而不是INSTEAD OF INSERT吗?

另外,假设它应该是UPDATE触发器,我通常会检查这种方式而不是WHERE子句:

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

好的,所以我坚持你试图使用而不是插入触发器来进行更新。问题是,而不是触发器要求您自己仍然执行插入操作,因为触发器正在运行而不是插入。试试这个(请注意,如果其他列与SHAPEX_Coord / Y_Coord一起插入,您还需要从inserted中提取这些列:< / p>

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;