А что такое "разные значения с предыдущего уровня" ?

Неправильно я написал.

Попробую объяснить на словах по другому:

Сам CTE называется "Tree"
Внутри CTE написан запрос с UNION. Первый SELECT обычный, а второй SELECT джойнит таблицу с CTE "Tree" Вот этот вот второй запрос и представляет интерес. Ты наверное заметил что я там обращался с "Tree" дважды. Первый раз в условии WHERE, а второй раз в списке возвращаемых полей в SELECT. Так вот в выражении WHERE используется значение из Tree, переданное так сказать с верхнего уровня рекурсии, а в выражении SELECT оно может быть или с верхнего уровня, или с текущего в зависимости от порядка полей.

Вот тебе скрипт:

CREATE TABLE "Phases" (
    "Id"        INTEGER NOT NULL,
    "ParentId"  INTEGER
);

CREATE GENERATOR "GenPhasesId";

SET TERM ^ ;
CREATE TRIGGER "Phases_BI" FOR "Phases"
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
  IF (NEW."Id" IS NULL) THEN
    NEW."Id" = NEXT VALUE FOR "GenPhasesId";
END^
SET TERM ; ^


INSERT INTO "Phases" ("Id", "ParentId") VALUES (1, NULL);
INSERT INTO "Phases" ("Id", "ParentId") VALUES (2, 1);
INSERT INTO "Phases" ("Id", "ParentId") VALUES (3, 2);
INSERT INTO "Phases" ("Id", "ParentId") VALUES (4, 1);
INSERT INTO "Phases" ("Id", "ParentId") VALUES (5, NULL);
INSERT INTO "Phases" ("Id", "ParentId") VALUES (6, 5);

SET GENERATOR "GenPhasesId" TO 6;

COMMIT;


Задача у меня была склонировать иерархию.

Этот запрос работает:

WITH RECURSIVE "Tree" ("OldId", "OldParentId", "NewParentId", "NewId") AS (
  SELECT "Id", "ParentId", CAST(NULL AS INTEGER), GEN_ID("GenPhasesId", 1)
    FROM "Phases" P WHERE P."ParentId" IS NULL
  UNION ALL
  SELECT P."Id", P."ParentId", T."NewId", GEN_ID("GenPhasesId", 1)
    FROM "Phases" P, "Tree" T WHERE P."ParentId" = T."OldId" )
SELECT "OldId", "OldParentId", "NewId", "NewParentId" FROM "Tree"


А этот вот не работает:

WITH RECURSIVE "Tree" ("OldId", "OldParentId", "NewId", "NewParentId") AS (
  SELECT "Id", "ParentId", GEN_ID("GenPhasesId", 1), CAST(NULL AS INTEGER)
    FROM "Phases" P WHERE P."ParentId" IS NULL
  UNION ALL
  SELECT P."Id", P."ParentId", GEN_ID("GenPhasesId", 1), T."NewId"
    FROM "Phases" P, "Tree" T WHERE P."ParentId" = T."OldId" )
SELECT "OldId", "OldParentId", "NewId", "NewParentId" FROM "Tree"

здесь T."NewId" успевает замениться на новое значение перед тем как выдаётся в результирующий набор. Вот именно на это я хочу обратить твоё внимание.

Нормально ли такое поведение с точки зрения стандарта, атомарности и
т.п. теории.
    А причём тут эти высокие материи ? :)

Я думаю а вдруг стандарт вещает что не должны подобные фантомы (или как их) выскакивать.

    Полям неизвестного типа назначается CHAR (чего-то там не помню, скорее 
всего 1).
В где тут проблемка ?

А чего ж тогда такой запрос работает?

SELECT NULL FROM RDB$DATABASE
UNION ALL
SELECT 100 FROM RDB$DATABASE

Ответить