Мне тут надо чтобы по запросу всегда выдавалась одна запись. Если записи
нет, то онна должна быть создана.
Для этого я состряпал нехитрую процедуру:
CREATE PROCEDURE GET_COMMENTING_THREAD(
OBJECT_ID INTEGER,
OBJECT_TYPE_ID INTEGER,
OWNER_ID INTEGER)
RETURNS (
"DB_KEY" CHAR(8) CHARACTER SET OCTETS)
AS
BEGIN
SELECT RDB$DB_KEY FROM "CommentingThreads" T
WHERE T."ObjectId" = :OBJECT_ID AND T."ObjectTypeId" = :OBJECT_TYPE_ID
INTO :DB_KEY;
IF (ROW_COUNT = 0) THEN
INSERT INTO "CommentingThreads" ("ObjectId", "ObjectTypeId", "OwnerId")
VALUES (:OBJECT_ID, :OBJECT_TYPE_ID, :OWNER_ID)
RETURNING RDB$DB_KEY INTO :DB_KEY;
SUSPEND;
END
Теперь вызываю её для уже созданной записи во вроде бы эквивалентных
запросах и наблюдаю подозрительное поведение во втором случае:
1) Всё нормально - два индексированнных чтения показывает. Ну оно и
понятно - сначала DB_KEY выбирается, а потом запись по нему.
SELECT T.* FROM GET_COMMENTING_THREAD(1, 1, 8) G
LEFT JOIN "CommentingThreads" T ON T.RDB$DB_KEY = G."DB_KEY"
PLAN JOIN (T INDEX (UNQ1_CommentingThreads), T INDEX ())
2) А вот тут лажа получается: DB_KEY в процедуре выгребается нормально,
а потом вся таблица целиком проходится
SELECT * FROM "CommentingThreads" T
WHERE T.RDB$DB_KEY = (SELECT "DB_KEY" FROM GET_COMMENTING_THREAD(2, 1, 8))
PLAN (T INDEX (UNQ1_CommentingThreads)) PLAN (T NATURAL)
На 2.1 проверить не могу. Читал что в 2.1 что-то фиксилось с ДБ-кеями.
Вот не знаю надо в трекер писать или нет...