Computed by

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
Вадим Снопов
Сообщения: 10
Зарегистрирован: 07 дек 2005, 04:33

Computed by

Сообщение Вадим Снопов » 07 дек 2005, 04:45

Странный глюк с полями cjmputed by.
Есть таблица

Код: Выделить всё

CREATE GENERATOR GEN_DOMAINS_ID;

CREATE TABLE DOMAINS (
    ID           INTEGER NOT NULL,
    NAME         NAME_PART /* NAME_PART = VARCHAR(16) */,
    PARENT       INTEGER,
    DNS_RECORD   COMPUTED BY ("NAME"||'.'||(select "FULL_NAME" from "GET_FQDN"("DOMAINS"."ID"))),
    FQDN         COMPUTED BY (SUBSTR("DNS_RECORD",1,STRLEN("DNS_RECORD")-1)),
    DNS          BOOLEAN NOT NULL /* BOOLEAN = SMALLINT DEFAULT 0 NOT NULL CHECK (value in (0,1)) */,
    PROJECT      BOOLEAN NOT NULL /* BOOLEAN = SMALLINT DEFAULT 0 NOT NULL CHECK (value in (0,1)) */,
    RECORD_TYPE  DNS_TYPES /* DNS_TYPES = VARCHAR(2) DEFAULT 'A' NOT NULL CHECK (value in ('A', 'MX')) */
);
ALTER TABLE DOMAINS ADD CONSTRAINT UNQ1_DOMAINS UNIQUE (NAME, PARENT);
ALTER TABLE DOMAINS ADD CONSTRAINT PK_DOMAINS PRIMARY KEY (ID);
ALTER TABLE DOMAINS ADD CONSTRAINT FK_DOMAINS_PARENT FOREIGN KEY (PARENT) REFERENCES DOMAINS (ID) ON DELETE SET NULL ON UPDATE SET NULL;

есть процедура
CREATE PROCEDURE GET_FQDN (
    INPUT_ID INTEGER)
RETURNS (
    FULL_NAME VARCHAR(128))
AS
DECLARE VARIABLE PARENT_DOMAIN INTEGER;
begin
  "FULL_NAME" = '**db_error**';
  select "PARENT" from "DOMAINS" where "DOMAINS"."ID" = :"INPUT_ID" into :"PARENT_DOMAIN";
  if("PARENT_DOMAIN" is not null) then
    begin
    select "DOMAINS"."DNS_RECORD" from "DOMAINS" where "DOMAINS"."ID" = :"PARENT_DOMAIN" into :"FULL_NAME";
    end
   else
    begin
     "FULL_NAME" = '';
    end
  suspend;
end
вкратце - простая реализация DNS-записей, используюя рекурсию.

Есть и глюк - вычисляемые поля то вычисляются, то нет - null.
В чем может быть дело. Ломал голову всю ночь - бестолку.
Кто имел дело с подобными штучками?
Справочно - глюк везде: из шелла (isql fb1.5.2), php --with-interbase, IBExpert

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 07 дек 2005, 08:32

Если любая часть выражения NULL (включая вложенный SELECT, ничего не вернувший) то и результат будет NULL.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 07 дек 2005, 09:45

за такие вычисляемые поля надо пальцы отрубать.
кроме того, домен boolean в следуюших версиях может стать зарезервированным словом. меняй, пока не поздно.

Вадим Снопов
Сообщения: 10
Зарегистрирован: 07 дек 2005, 04:33

Сообщение Вадим Снопов » 07 дек 2005, 12:11

и где тут null?
В том то и глюк, что то есть, то нет

Вадим Снопов
Сообщения: 10
Зарегистрирован: 07 дек 2005, 04:33

Сообщение Вадим Снопов » 07 дек 2005, 12:13

kdv писал(а):за такие вычисляемые поля надо пальцы отрубать.
кроме того, домен boolean в следуюших версиях может стать зарезервированным словом. меняй, пока не поздно.
Черт бы с boolean, а в чем кривизна? Или просто так размахиваем словами?

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 07 дек 2005, 13:48

Или просто так размахиваем словами?
я с InterBase работаю 11 лет, причем еще и обеспечиваю техническое сопровождение. Поэтому иногда (!) рекомендую прислушиваться к моим словам.

теперь по существу - сама идея строить полный домен вот таким образом мне не очень нравится. Я, конечно, задачи не знаю, но какой смысл? Например, мне в голову может прийти идея "перенести" субдомен forum с домена ibase.ru на домен yaffil.ru ? Вряд ли. Кроме того, любой select в вычисляемом столбце - путь к тормозам. Выглядит это "красиво", не спорю, но красиво в теории оказывается полной гадостью на практике.

Кроме того, при создании метаданных, допустим из скрипта, процедура должна быть создана раньше таблицы. А она рекурсивно завязана на таблицу. Получается тупик.
Лично я бы сделал обычный запрос, который бы заполнял в триггере.
процедурой, вытаскивающей "путь" как в www.ibase.ru/devinfo/treedb.htm (getparents). без всякой рекурсии.

Вадим Снопов
Сообщения: 10
Зарегистрирован: 07 дек 2005, 04:33

Сообщение Вадим Снопов » 07 дек 2005, 14:30

Извини за подозрение - ночка выдалась.
А что, по поводу
Кроме того, при создании метаданных, допустим из скрипта, процедура должна быть создана раньше таблицы. А она рекурсивно завязана на таблицу. Получается тупик.
Лично я бы сделал обычный запрос, который бы заполнял в триггере.
процедурой, вытаскивающей "путь" как в www.ibase.ru/devinfo/treedb.htm (getparents). без всякой рекурсии.
Действительно в ib (fb, yf) нельзя создавать неявных рекурсивных процедур? Жаль. И порядок создания метаданных тоже важен - ведь можно создать временное поле для использования в ХП, потом доюавить аналогичное, пересоздать ХП с использованием уже нового поля и мета в порядке - или нет?
Предложенный путь в статье по ссылке вполне нормальный, но я-то хотел красивее (тормоза здесь не так важны).[/quote]

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 07 дек 2005, 16:01

Действительно в ib (fb, yf) нельзя создавать неявных рекурсивных процедур? Жаль
да много чего можно, если парсер допускает. Только, например, можно все запросы в процедурах или триггерах выпонять через Execute statement. Но к каким результатам по производительности это приведет...

и еще вспомнилось приложение, которое выполняло запрос, порождающий файл сортировки в 1 гигабайт, это при БД размером 100 мегабайт.
но я-то хотел красивее
когда говорят такие фразы, хочется убежать куда подальше. :) Именно потому что "красивые решения" зачастую красивы
а) только в теории
б) только в уме того, кто считает это красивым.

Обратных примеров - масса. Для улучшения производительности и денормализацию иногда приходится делать, и избыточные данные вводить, или наоборот, дробить структуру таблицы на 2 или 3, и т.п. Эти решения тоже по своему красивы, потому что приводят к оптимальному результату. А "чистая красота" - это фантастика :)

Ответить