Обновляемый просмотр

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

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

Ответить
Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Обновляемый просмотр

Сообщение Lars » 20 сен 2006, 07:56

Есть базовая таблица, из которой необходимо запретить удаление.
Создан просмотр:

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

/******************************************************************************/
CREATE TABLE TBL_PRODUCT_REF (
    ID          DMN_PK NOT NULL /* DMN_PK = BIGINT NOT NULL */,
    NAME        DMN_NAME /* DMN_NAME = VARCHAR(80) DEFAULT ,
    STAND_TIME  DMN_INT /* DMN_INT = INTEGER DEFAULT 0 */,
    IS_DELETE   DMN_BOOLEAN /* DMN_BOOLEAN = SMALLINT DEFAULT 0 NOT NULL CHECK (VALUE IN (0, 1)) */
);




CREATE VIEW VW_TBL_PRODUCT_REF(
    ID,
    NAME,
    STAND_TIME)
AS
select
    ID,
    NAME,
    STAND_TIME
from
TBL_PRODUCT_REF
WHERE IS_DELETE=0;

ALTER TRIGGER VW_TBL_PRODUCT_REF_BD
AS
BEGIN
  UPDATE TBL_PRODUCT_REF SET IS_DELETE = 1
  WHERE (ID = OLD.ID);
END


ALTER TRIGGER VW_TBL_PRODUCT_REF_BI
AS
BEGIN
  INSERT INTO TBL_PRODUCT_REF (
    ID,
    NAME,
    STAND_TIME)
  VALUES (
    NEW.ID,
    NEW.NAME,
    NEW.STAND_TIME);
END

ALTER TRIGGER VW_TBL_PRODUCT_REF_BU
AS
BEGIN
  UPDATE TBL_PRODUCT_REF
  SET ID = NEW.ID,
      NAME = NEW.NAME,
      STAND_TIME = NEW.STAND_TIME
  WHERE (ID = OLD.ID);
END
Удаление производится из родной таблицы. Почему?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 20 сен 2006, 08:14

А не проще отобрать у юзера права на удаление?

Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Сообщение Lars » 20 сен 2006, 08:21

Ivan_Pisarevsky писал(а):А не проще отобрать у юзера права на удаление?
А потом в программе отлавливать exception!

Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Сообщение Lars » 20 сен 2006, 08:37

Как сделать VIEW изначально READ ONLY? Иначе он изменяемый по умолчанию для ОДНОЙ таблицы.

Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Сообщение Lars » 20 сен 2006, 08:51

Решение задачи не совсем обычное :evil:
Добавлена уникальность по NAME, и в спецификации VIEW указано DISTINCT, по рекомендации Х.Борри, чтобы создать ТОЛЬКО ДЛЯ ЧТЕНИЯ запрос.
триггер стал делать свое дело.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 20 сен 2006, 08:51

обычно люди джойнят с rdb$database

Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Сообщение Lars » 20 сен 2006, 09:01

Можно пример?
В чем принципиальное отличие моего подхода с DISTINCT.

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Сообщение dimitr » 20 сен 2006, 09:46

Lars писал(а):Можно пример?
В чем принципиальное отличие моего подхода с DISTINCT.

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

CREATE VIEW VW_TBL_PRODUCT_REF ( ID, NAME, STAND_TIME )
AS
select ID, NAME, STAND_TIME
from TBL_PRODUCT_REF join RDB$DATABASE ON 1 = 1
WHERE IS_DELETE = 0;
принципиальных отличий нет, окромя быстродействия - твой DISTINCT приведет к абсолютно ненужному SORT-плану. JOIN с одной записью тут выигрышнее.

Lars
Сообщения: 86
Зарегистрирован: 21 дек 2005, 16:34

Сообщение Lars » 20 сен 2006, 13:40

dimitr писал(а):
Lars писал(а):Можно пример?
В чем принципиальное отличие моего подхода с DISTINCT.

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

CREATE VIEW VW_TBL_PRODUCT_REF ( ID, NAME, STAND_TIME )
AS
select ID, NAME, STAND_TIME
from TBL_PRODUCT_REF join RDB$DATABASE ON 1 = 1
WHERE IS_DELETE = 0;
принципиальных отличий нет, окромя быстродействия - твой DISTINCT приведет к абсолютно ненужному SORT-плану. JOIN с одной записью тут выигрышнее.
Спасибо, помогло.

Ответить