Страница 1 из 1

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

Добавлено: 07 дек 2005, 08:32
Dimitry Sibiryakov
Если любая часть выражения NULL (включая вложенный SELECT, ничего не вернувший) то и результат будет NULL.

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

Добавлено: 07 дек 2005, 12:11
Вадим Снопов
и где тут null?
В том то и глюк, что то есть, то нет

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

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

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

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

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

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

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

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