我有一个而不是更新触发器,它在触发前评估条件,并且在触发器结束时,我想触发执行简单查询的更新后触发器。但是,我不确定后触发器是否是正确的解决方案,并且,无论如何,我在最后包含后触发器的笨拙尝试会导致许多语法错误。
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
Aaron是对的,这不会处理用户改变xy列和/或使用GIS应用程序移动点的更新情况,但是,当发生这种情况时,至少它不会崩溃。我认为更新后的触发器会处理它,但在此阶段,应用程序管理器的角色是在插入后跟踪罕见的点编辑。如果用户提供的X或Y为null,则几何将为null,并且定期DB维护将剔除这些记录,并将它们移动到位于大西洋某处的临时表,以进行手动位置确定。
答案 0 :(得分: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坐标全部填充时,或者当所有三个值都为空时,或者当x填充x时没有(或反之亦然)
答案 1 :(得分: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