Firebird РУКОВОДСТВО РАЗРАБОТЧИКА БАЗ ДАННЫХ
Шрифт:
EMP_NO FIRST_NAME LAST_NAME BIRTH_COUNTRY FULL_NAME
100 Maria Callas Maria Callas
Если вы разрабатываете приложения с использованием компонентов, которые генерируют операторы INSERT из спецификаций столбцов операторов SELECT для наборов данных - например, Delphi или JBuilder - учитывайте такое поведение, Если ваш компонент не поддерживает метод получения значений по умолчанию с сервера, может оказаться необходимым изменить оператор, записывающий данные.
При
Это вовсе не означает, что вы всегда должны опускать поля, обрабатываемые триггером, во входном списке. Очень рекомендуется для поддержания целостности данных создавать триггеры, которые присваивают значения столбцам в случае, когда такие значения не задаются в операторе INSERT - особенно когда используется множество приложений и инструментов для доступа к вашей базе данных. Триггер должен проверять входное значение (например, NULL) и выполнять свои действия в соответствии с условиями.
В следующем примере первичный ключ OID заполняется в триггере:
CREATE TABLE AIRCRAFT (
OID INTEGER NOT NULL,
REGISTRATION VARCHAR(8) NOT NULL,
CONSTRAINT PK_AIRCRAFT
PRIMARY KEY (OID));
COMMIT;
/**/
SET TERM ^;
CREATE TRIGGER BI_AIRCRAFT FOR AIRCRAFT
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.OID IS NULL) THEN
NEW.OID = GEN_ID(ANYGEH, 1) ;
END ^
SET TERM ;^
COMMIT;
/* */
INSERT INTO AIRCRAFT (REGISTRATION)
SELECT FIRST 3 SKIP 2 REGISTRATION FROM AIRCRAFT_OLD
ORDER BY REGISTRATION;
COMMIT;
В этом случае триггер получает значение генератора для первичного ключа, потому что ему не было передано значение во входном списке. При этом, поскольку триггер выполнит свою работу только в том случае, если обнаружит NULL, следующий оператор INSERT также будет прекрасно работать - конечно, при условии, что предоставляемое значение OID не нарушает ограничения уникальности для первичного ключа:
INSERT IN AIRCRAFT (OID, REGISTRATION)
VALUES(1033, 'ECHIDNA');
Когда вам нужно это делать? В Firebird удивительно часто. При реализации структур главная-подчиненная вы можете получить значение первичного ключа для главной строки из генератора до того, как строка будет отправлена в базу данных, простым вызовом DSQL:
SELECT GEN_ID(YOURGENERATOR, 1) FROM RDB$DATABASE;
Генераторы работают вне управления транзакций, и если вы получили номер, то он ваш. Вы можете использовать его для столбцов внешнего ключа подчиненных строк в клиентских буферах, если вы их создали, без сохранения главной строки в базе данных. Если пользователь решил отменить действия, то ничего не нужно "аннулировать" на сервере. Если вы когда-либо старались добиться подобной возможности в СУБД, которая использует автоинкрементный или "идентифицирующий" тип, вы полюбите такую возможность.
Другие аспекты этой техники см. в главе 31.
Оператор UPDATE
Оператор UPDATE
Обсуждение просмотров, которые могут принимать изменения для лежащих в их основе таблиц, см. в главе 24. Запрос UPDATE, который изменяет только текущую строку курсора, называется позиционированным изменением. Запрос, который может изменять множество строк, называется поисковым изменением.
Позиционированные операции в сравнении с поисковыми
Операторы UPDATE и DELETE могут быть позиционированными (выполняются над одной и только одной строкой) и поисковыми (выполняются над нулевым или большим количеством строк). Строго говоря, позиционированное изменение может появиться только в контексте текущей строки операции с курсором, в то время как поисковое изменение, возможно ограниченное условиями поиска в предложении WHERE, появляется во всех других контекстах.
Многие компоненты интерфейсов эмулируют позиционированные операции изменения и удаления, используя поисковое изменение с предложением WHERE, уникально определяющим строку. Такие однонаправленные или прокручиваемые классы наборов данных поддерживают "буфер текущей строки", который хранит или связан со столбцом и значением ключа той строки, которая была выбрана задачей пользователя для операции. Когда пользователь готов отправить запрос на изменение или удаление, компонент конструирует поисковый оператор INSERT или DELETE, который указывает на одну строку базы данных, используя первичный ключ (или любой другой уникальный список столбцов) в предложении WHERE.
! ! !
ВНИМАНИЕ! He все компоненты столь "сообразительны", чтобы определить наличие дубликатов строк в "живых" буферах. В таких продуктах задачей разработчика является убедиться в уникальности или найти любой другой способ защитить приложение от нежелаемого изменения множества строк.
. ! .
Использование оператора UPDATE
Оператор UPDATE имеет следующую основную форму:
UPDATE имя-таблицы | имя-просмотра
SET имя-столбца = значение [,имя-столбца = значение ...]
[WHERE <условие-поиска> | WHERE CURRENT OF имя-курсора]
При поисковых изменениях, если не задано предложение WHERE, то изменения будут выполнены для каждой строки таблицы.
Синтаксис предложения SET:
SET имя-столбца = значение [, имя-столбца = значение ...]
Предложение SET представляет собой список, указывающий каждый изменяемый столбец вместе с новым присваиваемым ему значением. Новое значение должно соответствовать определению столбца по типу и размеру. Если столбец допускает пустое значение, ему также может быть присвоено значение NULL.