powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Непонятки с check constraint
15 сообщений из 15, страница 1 из 1
Непонятки с check constraint
    #39400962
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Привет.

Есть таблица:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
create table T (
    GROUP_ID   integer not null,
    ITEM_ID    integer not null,
    PARENT_ID  integer
);

alter table T
  add constraint PK_T
      primary key ( GROUP_ID, ITEM_ID );


Поле PARENT_ID может быть либо null, либо ссылаться на другую запись в рамках GROUP_ID, но не на саму себя.

Накладываю ограничение:
Код: sql
1.
2.
3.
4.
5.
6.
alter table T
  add constraint CHK_T check ( ( PARENT_ID is null ) or
                               ( PARENT_ID in ( select ttt.ITEM_ID
                                                  from T as ttt
                                                 where ttt.GROUP_ID = GROUP_ID
                                                   and ttt.ITEM_ID <> ITEM_ID ) ) );



Добваляю данные:
Код: sql
1.
2.
3.
4.
5.
6.
7.
insert into T ( GROUP_ID, ITEM_ID, PARENT_ID )
       values ( 1,        1,       null      );
insert into T ( GROUP_ID, ITEM_ID, PARENT_ID )
       values ( 1,        2,       null      );
insert into T ( GROUP_ID, ITEM_ID, PARENT_ID )
       values ( 1,        3,       null      );
commit;


При попытке изменить значение поля PARENT_ID на любое, кроме null, вызывает ругань на нарушение констрейнта CHK_T.

Удаляю констрейнт CHK_T и добавляю его в виде FK и CHECK:
Код: sql
1.
2.
3.
4.
5.
6.
alter table T
  add constraint FK_T
      foreign key ( GROUP_ID, PARENT_ID ) references T ( GROUP_ID, ITEM_ID );

alter table T
  add constraint CHK_T check ( PARENT_ID <> ITEM_ID );


В таком варианте ограничения работают правильно.

Что не так в первом варианте CHK_T?

С уважением, Polesov.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39400976
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovЧто не так в первом варианте CHK_T?
Всё, начиная с самой сумасшедшей идеи запихнуть в ограничение запрос.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39400982
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

т.е. с виду правильный запрос в рамках ограничения работает неправильно?
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39400988
pastor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovDimitry Sibiryakov,

т.е. с виду правильный запрос в рамках ограничения работает неправильно?

Он неправильный.

FK, PK и прочие индексы внетранзакционны в отличие от.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39400996
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
pastor, понятно. Спасибо.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401169
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovНакладываю ограничение:
за select в check constraint надо хотя бы на пару дней лишать еды.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401174
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Kdv!
You wrote on 8 февраля 2017 г. 18:17:51:

Kdv> за select в check constraint надо хотя бы на пару дней лишать еды.
От полётов отстранить.
Ста грамм не давать.
Назначить дежурным, вечным дежурным по аэродрому!
(c)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401177
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А как же традиционное "линейкой по пальцам"? по идее должно давать эффект поскорее, хотя и выветривается, пожалуй, быстрее.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401179
Мимопроходящий
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Hello, Ivan Pisarevsky!
You wrote on 8 февраля 2017 г. 18:31:01:

Ivan Pisarevsky> А как же традиционное "линейкой по пальцам"? по идее должно давать эффект поскорее, хотя и выветривается, пожалуй, быстрее.не будем ограничиваться полумерами!


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401196
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_PisarevskyА как же традиционное "линейкой по пальцам"? по идее должно давать эффект поскорее, хотя и
выветривается, пожалуй, быстрее.

Это смотря какая линейка. Видал я таких монстров, которые и за гильотину сойдут.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401481
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Апну тему.

Все же вопрос был не в том, хорошо или плохо использовать запрос в check constraint, а почему в запросе не выполняется условие.
Запрос в check такой:
Код: sql
1.
2.
3.
4.
select ttt.ITEM_ID
  from T as ttt
 where ttt.GROUP_ID = GROUP_ID
   and ttt.ITEM_ID <> ITEM_ID


Попытка присвоения полю ITEM_ID любого значения, отличного от null и удовлетворяющего условию ограничения, вызывает ошибку:
Код: powershell
1.
2.
3.
Operation violates CHECK constraint  on view or table.
Operation violates CHECK constraint CHK_T on view or table T.
At trigger 'CHECK_2'.



Такое впечатление, что в условии where запроса
Код: sql
1.
2.
  where ttt.GROUP_ID = GROUP_ID
    and ttt.ITEM_ID <> ITEM_ID

значения GROUP_ID и ITEM_ID берутся из контекста самого запроса, а не из контекста текущей записи.

С уважением, Polesov.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401485
Ivan_Pisarevsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PolesovВсе же вопрос был не в том, хорошо или плохо использовать запрос в check constraintне хорошо или плохо, а нельзя.

Polesovзначения GROUP_ID и ITEM_ID берутся из контекста самого запросаразумеется.

используй триггер и его контекстные переменные old/new
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401489
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ivan_Pisarevsky,

ограничение нормально реализуется через FK и CHECK
Код: sql
1.
2.
3.
4.
5.
6.
alter table T
  add constraint FK_T
      foreign key ( GROUP_ID, PARENT_ID ) references T ( GROUP_ID, ITEM_ID );

alter table T
  add constraint CHK_T check ( PARENT_ID <> ITEM_ID );



С запросом в CHECK CONSTRAINT теперь понятно, только в документации я про это ничего не нашел.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39401507
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Гипотетический случай.

Требуется в некой таблице хранить идентификаторы и имена системных типов. Наложить FK на таблицу RDB$TYPES нельзя, поэтому:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table T (
    ID         integer not null primary key,
    TYPE_ID    integer,
    TYPE_NAME  char(31) character set UNICODE_FSS
);

alter table T
  add constraint CHK_T check ( ( TYPE_NAME is null ) or
                               ( TYPE_NAME in ( select RDB$TYPE_NAME
                                                  from RDB$TYPES t
                                                 where t.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
                                                   and t.RDB$TYPE = TYPE_ID ) ) );

В таком варианте ограничение работает правильно.

Изменим имена полей так, что бы они совпадали с именами системной таблицы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create table T (
    ID             integer not null primary key,
    RDB$TYPE       integer,
    RDB$TYPE_NAME  char(31) character set UNICODE_FSS
);

alter table T
  add constraint CHK_T check ( ( RDB$TYPE_NAME is null ) or
                               ( RDB$TYPE_NAME in ( select RDB$TYPE_NAME
                                                      from RDB$TYPES t
                                                     where t.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
                                                       and t.RDB$TYPE = RDB$TYPE ) ) );

В таком варианте ограничение перестает работает.

Получается, что при совпадении имени поля его значение берется из контекста запроса, а не текущей записи.
...
Рейтинг: 0 / 0
Непонятки с check constraint
    #39525324
Polesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Апну тему.

PolesovПолучается, что при совпадении имени поля его значение берется из контекста запроса, а не текущей записи.
В таких случаях надо явно указывать имя таблицы:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
create table TBL (
    ID             integer not null primary key,
    RDB$TYPE       integer,
    RDB$TYPE_NAME  char(31) character set UNICODE_FSS
);

alter table TBL
  add constraint CHK_TBL
      check ( ( tbl.RDB$TYPE_NAME is null ) or
              ( tbl.RDB$TYPE_NAME in ( select rdb.RDB$TYPE_NAME
                                         from RDB$TYPES rdb
                                        where rdb.RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
                                          and rdb.RDB$TYPE = tbl.RDB$TYPE ) ) );
...
Рейтинг: 0 / 0
15 сообщений из 15, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Непонятки с check constraint
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]