将查询功能转换为 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 中获取 lftrgt 值。你基本上需要从变量中删除所有 @

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。删除、更新和插入邻接模型的效率要高得多。递归查询的检索性能非常好(尽管可能不如嵌套集模型好)。但是邻接模型还可以让你定义外键,这也是一个很大的优势。