C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Внешние ключи Firebird
Valdemar
Отправлено: 26.01.2007, 13:34


Мастер участка

Группа: Участник
Сообщений: 433



У меня есть таблица, у которой на одно поле наложено ограничение внешним ключом. Сделано это с целью не допустить записи в это поле значения, которого нет в другой таблице-справочнике. При удалении записи из справочной таблицы поле в связанной таблице очищается в NULL — это делает внешний ключ.
Но появилась необходимость при некоторых ситуациях поле с внешним ключом очистить, т.е. записать в него NULL. А внешний ключ этого сделать не дает, т.к. в таблице-справочнике нет записи, соответствующей значению NULL.
Можно ли это как-то побороть?
Я, конеччно, могу сделать триггеры вместо использования внешнего ключа. Один триггер будет срабатывать после удаления записи из справочной таблицы и очищать поле в связанной таблице. И два триггера перед вставкой и перед изменением таблицы будут проверять наличие соответствующей записи в таблице-справочнике.

Может есть другие варианты решения задачи?
AVC
Отправлено: 26.01.2007, 13:44


Ветеран

Группа: Модератор
Сообщений: 1583



Проверьте по синтаксису для FB. Обычно это ограничение (not Null или Null) указывается при создании таблицы как свойство поля.
Valdemar
Отправлено: 26.01.2007, 14:18


Мастер участка

Группа: Участник
Сообщений: 433



В свойствах поля указано, что оно может быть пустым.
Если при добавлении новой записи в поле с внешним ключом ничего не записывать, то все нормально. А вот если в поле что-то было записано, а потом его попробовать очистить, то получаю ошибку, внешний ключ не дает это сделать.
AVC
Отправлено: 26.01.2007, 14:34


Ветеран

Группа: Модератор
Сообщений: 1583



Странно. ohmy.gif
Вы меня заинтересовали. Сейчас разгоню FB и посмотрю.
AVC
Отправлено: 26.01.2007, 15:05


Ветеран

Группа: Модератор
Сообщений: 1583



QUOTE

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

CODE

/*
CREATE TABLE B
(bid INTEGER not Null primary key
,b_name char (80)
);

CREATE TABLE A
(aid INTEGER not Null primary key
,a_name char (80)
,bid integer
);

Alter Table A add foreign key (bid) references B (bid);
*/

--Insert Into B (bid, b_name)      Values (1, 'B1');       -- ok
--Insert Into A (aid, a_name, bid) Values (1, 'A1', 1);    -- ok
--Insert Into A (aid, a_name, bid) Values (2, 'A2', 2);    -- error
--Insert Into A (aid, a_name, bid) Values (3, 'A3', Null); -- ok

--Update A Set bid = Null Where aid = 1; -- ok
--Update A Set bid = 2    Where aid = 1; -- error
--Update A Set bid = 1    Where aid = 1; -- ok
Update A Set bid = Null Where aid = 1; -- ok

Комментарии нужны?
Valdemar
Отправлено: 26.01.2007, 15:42


Мастер участка

Группа: Участник
Сообщений: 433



Нет, комментарии не нужны. При выполнении Ваших SQL-команд ошибки нет. Эта ошибка у меня получается при выполнении с использованием FibPlus следующего кода:
CODE
FibDataSet->Edit();
FibDataSet->FBN("filed")->AsInteger=NULL;
FibDataSet->Post();

Для FibDataSet заданы SQL команды для выборки, вставки, удаления и модификации.

Вот только что пришла мысль, что может надо писать не AsInteger=NULL, а Value=NULL. Приду домой, попробую.
AVC
Отправлено: 26.01.2007, 15:51


Ветеран

Группа: Модератор
Сообщений: 1583



Ну вы и сами поняли. Только не NULL.
NULL — это 0
а Null это Variant().AsType(varNull) (в bcb6 не определен)

Вернуться в Работа с базами данных в C++Builder