несовместимый триггер SQL - PullRequest
0 голосов
/ 04 апреля 2011

Будучи новичком в SQL, могут ли некоторые помочь мне адаптировать этот триггер для sqlite или HSQLDB, или, может быть, предложить другой подход?

У меня есть эта таблица в моей базе данных:

CREATE TABLE IF NOT EXISTS dfTree 
(
id INTEGER, 
parentId INTEGER,
name VARCHAR(20),
depth INTEGER,
lineage VARCHAR(100)
)

Я пытаюсь установить триггер, но он кажется несовместимым с обоими БД, которые я пробовал (sqlite и HSQLDB)

CREATE TRIGGER dfTree_InsertTrigger ON dfTree
FOR INSERT AS
UPDATE child
    -- set the depth of this "child" to be the
    -- depth of the parent, plus one.
    SET depth = ISNULL(parent.depth + 1,0),
    -- the lineage is simply the lineage of the parent,
    -- plus the child's ID (and appropriate '/' characters
    lineage = ISNULL(parent.lineage,'/') + LTrim(Str(child.id)) + '/'
-- we can't update the "inserted" table directly,
-- so we find the corresponding child in the
-- "real" table
FROM dfTree child INNER JOIN inserted i ON i.id=child.id
-- now, we attempt to find the parent of this
-- "child" - but it might not exist, so these
-- values may well be NULL
LEFT OUTER JOIN dfTree parent ON child.parentId=parent.id

(Триггер должен вычислять поля "глубина" и "линия" при новой записиЯ слежу за статьей о древовидных структурах в http://www.developerfusion.com/article/4633/tree-structures-in-aspnet-and-sql-server/2/

Опять же, будучи новичком в SQL, некоторые могут помочь мне адаптировать этот триггер для sqlite или HSQLDB, или, возможно, предложить другой подход?

Спасибо!

1 Ответ

0 голосов
/ 04 апреля 2011

Это должно работать:

CREATE TRIGGER dfTree_InsertTrigger 
after insert ON dfTree 
for each row
begin
  UPDATE dftree SET   
    depth = (select coalesce(depth + 1, 1) from (select depth from dftree parent where parent.id = new.parentid union all select null depth)),
    lineage = (select coalesce(lineage,'/') || dftree.id || '/' from (select lineage from dftree parent where parent.id = new.parentid union all select null lineage))
  where new.id = id;
end;

Пара замечаний:
- оператор объединения строк в SQL - это ||, а не +
- coalesce () должен быть более переносимым, чемisnull
- часть union all .. гарантирует, что мы всегда получим строку (даже если родитель не существует)

...