需要帮助编写 PostgreSQL 触发器函数
我有两个表代表两种不同类型的图像。我正在使用 PostGIS 来表示这些图像的边界。下面是这些表的一个简化示例:
CREATE TABLE img_format_a (
id SERIAL PRIMARY KEY,
file_path VARCHAR(1000),
boundary GEOGRAPHY(POLYGON, 4326)
);
CREATE TABLE img_format_p (
id SERIAL PRIMARY KEY,
file_path VARCHAR(1000),
boundary GEOGRAPHY(POLYGON, 4326)
);
我还有一个交叉引用表,我希望其中包含彼此重叠的图像的所有 ID。每当“A”类型的图像插入数据库时,我想检查它是否与“P”类型的任何现有图像重叠(反之亦然),并将相应的条目插入到 img_a_img_p交叉引用表。该表应该表示多对多关系。
我的第一反应是编写一个触发器来管理这个img_a_img_p
表。我以前从未创建过触发器,所以请告诉我这是否是一件愚蠢的事情,但这对我来说似乎很有意义。所以我创建了以下触发器:
CREATE TRIGGER update_a_p_cross_reference
AFTER INSERT OR DELETE OR UPDATE OF boundary
ON img_format_p FOR EACH ROW
EXECUTE PROCEDURE check_p_cross_reference();
我遇到困难的部分是编写触发器函数。我的代码是用 Java 编写的,我看到有像 PL/pgSQL 这样的工具,但我不确定这是否是我应该使用的,或者我是否需要这些特殊的附加组件之一。
基本上,我需要触发器做的就是每次将新图像插入 img_format_a
或 img_format_p
时更新交叉引用表。插入新图像时,我想使用 ST_Intersects 等 PostGIS 函数来确定新图像是否与其他表中的任何图像重叠。对于 ST_INTERSECTS
返回 true 的每个图像对,我想在 img_a_img_p
中插入一个新条目,其中包含两个图像的 ID。有人可以帮我弄清楚如何编写这个触发函数吗?这是一些伪代码:
SELECT * FROM img_format_p P
WHERE ST_Intersects(A.boundary, P.boundary);
for each match in selection {
INSERT INTO img_a_img_p VALUES (A.id, P.id);
}
I have two tables representing two different types of imagery. I am using PostGIS to represent the boundaries of those images. Here is a simplified example of those tables:
CREATE TABLE img_format_a (
id SERIAL PRIMARY KEY,
file_path VARCHAR(1000),
boundary GEOGRAPHY(POLYGON, 4326)
);
CREATE TABLE img_format_p (
id SERIAL PRIMARY KEY,
file_path VARCHAR(1000),
boundary GEOGRAPHY(POLYGON, 4326)
);
I also have a cross reference table, which I want to contain all the IDs of the images that overlap each other. Whenever an image of type "A" gets inserted into the database, I want to check to see whether it overlaps any of the existing imagery of type "P" (and vice versa) and insert corresponding entries into the img_a_img_p
cross reference table. This table should represent a many-to-many relationship.
My first instinct is to write a trigger to manage thisimg_a_img_p
table. I've never created a trigger before, so let me know if this is a silly thing to do, but it seems to make sense to me. So I create the following trigger:
CREATE TRIGGER update_a_p_cross_reference
AFTER INSERT OR DELETE OR UPDATE OF boundary
ON img_format_p FOR EACH ROW
EXECUTE PROCEDURE check_p_cross_reference();
The part where I am getting stuck is with writing the trigger function. My code is in Java and I see that there are tools like PL/pgSQL, but I'm not sure if that's what I should use or if I even need one of those special add-ons.
Essentially all I need the trigger to do is update the cross reference table each time a new image gets inserted into either img_format_a
or img_format_p
. When a new image is inserted, I would like to use a PostGIS function like ST_Intersects
to determine whether the new image overlaps with any of the images in the other table. For each image pair where ST_INTERSECTS
returns true, I would like to insert a new entry into img_a_img_p
with the ID's of both images. Can someone help me figure out how to write this trigger function? Here is some pseudocode:
SELECT * FROM img_format_p P
WHERE ST_Intersects(A.boundary, P.boundary);
for each match in selection {
INSERT INTO img_a_img_p VALUES (A.id, P.id);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以将通常的
INSERT ... SELECT
习惯用法包装在 PL/pgSQL 函数中,如下所示:触发器有两个额外的变量,
新
和旧
:因此,您可以使用
NEW.id
访问即将输入的新img_format_p
值。您(当前)不能使用普通 SQL 语言作为触发器:但 PL/pgSQL 非常接近。这作为 AFTER INSERT 触发器是有意义的:
可以使用
img_a_img_p
上的外键和级联删除。您也可以使用触发器进行更新:但您可能希望在插入新条目之前清除旧条目,例如:
在
INSERT...SELECT
语句之前。You could wrap the usual
INSERT ... SELECT
idiom in a PL/pgSQL function sort of like this:Triggers have two extra variables,
NEW
andOLD
:So you can use
NEW.id
to access the newimg_format_p
value that's going in. You (currently) can't use the plain SQL language for triggers:but PL/pgSQL is pretty close. This would make sense as an AFTER INSERT trigger:
Deletes could be handled with a foreign key on
img_a_img_p
and a cascading delete. You could use your trigger for UPDATEs as well:but you'd probably want to clear out the old entries before inserting the new ones with something like:
before the
INSERT...SELECT
statement.