我有鄰接表表賬號,與列ID,代碼,名,並PARENT_ID。 爲了使排序和顯示更容易,我添加了兩列:深度和路徑(物化路徑)。我知道,postgresql具有物化路徑的專用數據類型,但我想使用更通用的方法,而不是特定於postgresql。我還在我的設計中應用了幾條規則:
1)代碼可以長達10個字符
2)最大深度爲9;所以根賬戶最多可以有8個子賬戶。
3)一旦設置,parent_id永遠不會改變,所以沒有必要將樹的分支移動到樹的另一部分。
4)路徑是一個帳戶的物化路徑,最長可達90個字符;它是通過連接帳戶代碼構建的,右側填充爲10個字符;例如,像'10000______10001______'。
因此,自動保持深度和路徑列,我創建了一個觸發併爲賬號表觸發功能:PostgreSQL中,保持分層數據與觸發器
CREATE FUNCTION public.fn_account_set_hierarchy()
RETURNS TRIGGER AS $$
DECLARE d INTEGER; p CHARACTER VARYING;
BEGIN
IF TG_OP = 'INSERT' THEN
IF NEW.parent_id IS NULL THEN
NEW.depth := 1;
NEW.path := rpad(NEW.code, 10);
ELSE
BEGIN
SELECT depth, path INTO d, p
FROM public.account
WHERE id = NEW.parent_id;
NEW.depth := d + 1;
NEW.path := p || rpad(NEW.code, 10);
END;
END IF;
ELSE
IF NEW.code IS DISTINCT FROM OLD.code THEN
UPDATE public.account
SET path = OVERLAY(path PLACING rpad(NEW.code, 10)
FROM (OLD.depth - 1) * 10 + 1 FOR 10)
WHERE SUBSTRING(path FROM (OLD.depth - 1) * 10 + 1 FOR 10) =
rpad(OLD.code, 10);
END IF;
END IF;
RETURN NEW;
END$$
LANGUAGE plpgsql
CREATE TRIGGER tg_account_set_hierarchy
BEFORE INSERT OR UPDATE ON public.account
FOR EACH ROW
EXECUTE PROCEDURE public.fn_account_set_hierarchy();
以上似乎INSERT的工作。但對於UPDATE,則會引發錯誤:「表'帳戶'上的UPDATE語句預計會更新1行;匹配0。」我對「UPDATE public.account ...」部分有疑問。有人可以幫助我糾正上述觸發器嗎?