将查询功能转换为 postgresql 触发器
Convert functionality of query to postgresql trigger
我有一个 table ctg:
CREATE TABLE ctg
(
id_ctg serial primary key,
lft INT NOT NULL,
rgt INT NOT NULL
);
以及删除行后执行函数的触发器:
CREATE TRIGGER ctg_el_del
AFTER DELETE ON ctg
FOR EACH ROW
EXECUTE PROCEDURE trigger_function();
CREATE FUNCTION trigger_function() RETURNS TRIGGER AS $$
BEGIN
/* deleting row and and his children */
END
$$
LANGUAGE plpgsql;
用于删除 MySQL 中的行和子项 我使用了查询:
SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1 FROM ctg WHERE id = 3; /* id of element which I want to delete */
DELETE FROM ctg WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE ctg SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE ctg SET lft = lft - @myWidth WHERE lft > @myRight;
如何在 trigger_function() 中正确使用此查询?
我正在使用嵌套集模型:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
这非常简单明了。您不需要 select 即可从已删除的 table 中获取 lft
和 rgt
值。你基本上需要从变量中删除所有 @
。
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS TRIGGER
AS $$
declare
myleft integer;
myright integer;
mywidth integer;
BEGIN
myleft := old.lft;
myright := old.rgt;
mywidth := old.rgt - old.lft + 1;
DELETE FROM ctg
WHERE lft BETWEEN myleft AND myright
AND id <> old.id; -- just to be sure
UPDATE ctg
SET rgt = rgt - mywidth
WHERE rgt > myRight;
UPDATE ctg
SET lft = lft - myWidth
WHERE lft > myRight;
return old;
END
$$
LANGUAGE plpgsql;
有关PL/pgSQL和触发器的更多详细信息,请参阅手册:
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html
顺便说一句:Postgres 可以很好地处理邻接模型,因为它支持 recursive queries。删除、更新和插入邻接模型的效率要高得多。递归查询的检索性能非常好(尽管可能不如嵌套集模型好)。但是邻接模型还可以让你定义外键,这也是一个很大的优势。
我有一个 table ctg:
CREATE TABLE ctg
(
id_ctg serial primary key,
lft INT NOT NULL,
rgt INT NOT NULL
);
以及删除行后执行函数的触发器:
CREATE TRIGGER ctg_el_del
AFTER DELETE ON ctg
FOR EACH ROW
EXECUTE PROCEDURE trigger_function();
CREATE FUNCTION trigger_function() RETURNS TRIGGER AS $$
BEGIN
/* deleting row and and his children */
END
$$
LANGUAGE plpgsql;
用于删除 MySQL 中的行和子项 我使用了查询:
SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1 FROM ctg WHERE id = 3; /* id of element which I want to delete */
DELETE FROM ctg WHERE lft BETWEEN @myLeft AND @myRight;
UPDATE ctg SET rgt = rgt - @myWidth WHERE rgt > @myRight;
UPDATE ctg SET lft = lft - @myWidth WHERE lft > @myRight;
如何在 trigger_function() 中正确使用此查询?
我正在使用嵌套集模型:http://mikehillyer.com/articles/managing-hierarchical-data-in-mysql/
这非常简单明了。您不需要 select 即可从已删除的 table 中获取 lft
和 rgt
值。你基本上需要从变量中删除所有 @
。
CREATE OR REPLACE FUNCTION trigger_function()
RETURNS TRIGGER
AS $$
declare
myleft integer;
myright integer;
mywidth integer;
BEGIN
myleft := old.lft;
myright := old.rgt;
mywidth := old.rgt - old.lft + 1;
DELETE FROM ctg
WHERE lft BETWEEN myleft AND myright
AND id <> old.id; -- just to be sure
UPDATE ctg
SET rgt = rgt - mywidth
WHERE rgt > myRight;
UPDATE ctg
SET lft = lft - myWidth
WHERE lft > myRight;
return old;
END
$$
LANGUAGE plpgsql;
有关PL/pgSQL和触发器的更多详细信息,请参阅手册:
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html
顺便说一句:Postgres 可以很好地处理邻接模型,因为它支持 recursive queries。删除、更新和插入邻接模型的效率要高得多。递归查询的检索性能非常好(尽管可能不如嵌套集模型好)。但是邻接模型还可以让你定义外键,这也是一个很大的优势。