Понимание SQL
Шрифт:
EXEC SQL DECLARE CURSOR High_Cust AS
SELECT *
FROM Salespeople
WHERE snum IN
(SELECT snum
FROM Customers
WHERE rating=300)
FOR UPDATE OF comm;
Это обеспечит вас определенной защитой от случайных модификаций, которые могут разрушить весь порядок в базе данных.
Пустые (NULLS) значения - это специальные маркеры определяемые самой SQL. Они не могут помещаться в главные переменные. Попытка вставить NULL значения в главнуюпеременную будет некорректна, так как главные языки не поддерживают NULL значений в SQL, по определению. Хотя результат при попытке вставить NULL
целого типа, i_a и i_b. (Нет ничего такого в разделеобьявлений, что могло бы представить их как переменные indicator. Они станут переменными indicator, когда будут использоваться как переменные indicator. )
Имеется одна возможность:
EXEC SQL OPEN CURSOR High_cust;
while SQLCODE=O do
begin
EXEC SQL FETCH High_cust
INTO :id_num, :salesperson,
:loc:i_a, :commINDlCATOR:i_b;
If i_a >=O and i_b >=O then
{no NULLs produced}
EXEC SQL UPDATE Salespeople
SET comm=comm + .01
WHERE CURRENT OF Hlgh_cust;
else
{one or both NULL}
begin
If i_a < O then
writeln ('salesperson ', id_num, ' has no city');
If i_b < O then
writeln ('salesperson ', id_num, ' has no
commission');
end;
{else}
end; {while}
EXEC SQL CLOSE CURSOR High_cust;
Как вы видите, мы включили, ключевое слово INDICATOR в одном случае, и исключили его в другом случае, чтобы показать, что эффект будет одинаковым в любом случае. Каждая строка будет выбрана, но команда UPDATE выполнится только если NULL значения не будут обнаружены. Если будут обнаружены NULL значения, выполнится еще одна часть программы, которая распечатает предупреждающее сообщение, где было найдено каждое NULL значение.
Обратите внимание: переменные indicator должны проверяться в главном языке, как указывалось выше, а не в предложении WHERE команды SQL. Последнее в принципе не запрещено, но результат часто бывает непредвиденным.
Другая возможность состоит в том, чтобы обрабатывать переменную indicator, связывая ее с каждой переменной главного языка, специальным способом, эмулирующим поведение NULL значений SQL.
сякий раз, когда вы используете
If sity='London' then
comm:=comm + .01
else comm:=comm - .01
Любое значение, вводимое в переменную city, или будет равно "London" или не будет равно. Следовательно, в каждом случае значение комиссионных будет либо увеличино либо уменьшено. Однако, эквивалентные команды в SQL выполняются по разному:
EXEC SQL UPDATE Salespeople
SET comm=comm + .01
WHERE sity='London';
и
EXEC SQL UPDATE Salespeople
SET comm=comm .01;
WHERE sity < > 'London';
( Вариант на ПАСКАЛе работает только с единственным значением, в то время как вариант на SQL работает со всеми таблицами. ) Если значение city в варианте на SQL будет равно значению NULL, оба предиката будут неизвестны, и значение comm, следовательно, не будет изменено в любом случае.
Вы можете использовать переменную indicator чтобы сделать поведение вашего главного языка непротиворечащим этому, с помощью создания условия, которое исключает NULL значения:
If i_city >=O then
begin
If city='London' then
comm:=comm + .01
else comm:=comm - .01;
end;
{begin and end нужны здесь только для понимания}
– -------------------------------------------------------------
ПРИМЕЧАНИЕ: Последняя строка этого примера содержит ремарку -
{ begin и end необходимы только для понимания }
– -------------------------------------------------------------
В более сложной программ, вы можете захотеть установить Булеву переменную в "верно", чтобы указать что значение city=NULL. Затем вы можете просто проверять эту переменную всякий раз, когда вам это необходимо.
ДРУГОЕ ИСПОЛЬЗОВАНИЕ ПЕРЕМЕННОЙ INDICATOR
Переменная indicator также может использоваться для назначения значения NULL. Просто добавьте ее к имени главной переменной в команде UPDATE или INSERT тем же способом что и в команде SELECT. Если переменная indicator имеет отрицательное значение, значение NULL будет помещено в поле. Например, следующая команда помещает значения NULL в поля city и comm, таблицы Продавцов, всякий раз, когда переменные indicator - i_a или i_b будут отрицательными; в противном случае она помещает туда значения главных переменных:
EXEC SQL INSERT INTO Salespeople
VALUES (:Id_num, :salesperson, :loc:i_a, :comm:i_b);
Переменная indicator используется также, чтобы показывать отбрасываемую строку. Это произойдет если вы вставляете значения символов SQL в главную переменную которая не достаточно длинна чтобы вместить все символы. Это особая проблема с нестандартным типами данных - VARCHAR и LONG (смотри Приложению C). В этом случае, переменная будет заполнена первыми символами строки, а последние символы будут потеряны. Если используется переменная indicator, она будет установлена в положительное значение, указывающее на длину отбрасываемой части строки, позволяя таким образом вам узнать, сколько символов было потеряно.