Грубер Мартин
Шрифт:
(SELECT snum
FROM Customers b
WHERE a.cnum=b.cnum);
{ Мы пока еще используем здесь SQL для выполнения основной работы.
Запрос выше размещает строки таблицы Порядков которые не согласуются с таблицей Заказчиков. }
EXEC SQL DECLARE Cust_assigns AS CURSOR FOR
SELECT cnum, snum
FROM Customers;
{Этот курсор используется для получения правильных значений snum}
begin { основная программа }
EXEC SQL OPEN CURSOR Wrong_Orders;
while SQLCODE=O do
{Цикл до тех пор пока Wrong_Orders не опустеет}
begin
EXEC SQL FETCH Wrong_Orders INTO
(:cnum, :snum);
if SQLCODE=O then
begin
{Когда Wrong_Orders опустеет, мы не хотели бы продолжать выполнение
этого цикла до бесконечности}
EXEC SQL OPEN CURSOR Cust_Assigns;
repeat
EXEC SQL FETCH Cust_Assigns
INTO (:custnum, :salesnum);
until :custnum=:cnum;
{Повторять FETCH до тех пор пока ... команда будет просматривать Cust_Assigns курсор до строки которая соответствует текущему значению cnum найденого в Wrong_Orders}
EXEC SQL CLOSE CURSOR Cust_assigns;
{Поэтому мы будем начинать новый вывод в следующий раз через цикл.
Значение в котором мы получим из этого курсора сохраняется в переменной - salesnum.}
EXEC SQL UPDATE Orders
SET snum=:salesnum
WHERE CURRENT OF Wrong_Orders;
end; {Если SQLCODE=0}.
end; { Пока SQLCODE . . . выполнить }
EXEC SQL CLOSE CURSOR Wrong_Orders;
* end; { основная программа }
Для данной программы которую я использовал, решение будет состоять в том, чтобы просто включить поле onum, первичным ключом таблицы Порядков, в курсор Wrong_Orders. В команде UPDATE, вы будете затем использовать предикат WHERE onum=:ordernum (считая целую переменную - odernum, обьявленной), вместо WHERE CURRENT Of Wrong_Orders.
Результатом будет программа наподобии этой (большинство комментариев из предыдущей программы здесь исключены ):
EXEC SQL BEGIN DECLARE SECTION;
SQLCODE: integer;
odernum integer;
cnum integer;
snum integer;
custnum: integer;
salesnum: integer;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE Wrong_Orders AS CURSOR FOR
SELECT onum, cnum, snum
FROM Orders a
WHERE snum < >
(SELECT snum
FROM Customers b
WHERE a.cnum=b.cnum);
EXEC SQL DECLARE Cust _ assigns AS CURSOR FOR
SELECT cnum, snum
FROM Customers;
begin { основная программа }
EXEC SQL OPEN CURSOR Wrong_Orders;
while SQLCODE=O do {Цикл до тех пор пока Wrong_Orders не опустеет}
begin
EXEC SQL FETCH Wrong_Orders
INTO (:odernum, :cnum, :snum);
if SQLCODE=O then
begin
EXEC SQL OPEN CURSOR Cust_Assigns;
repeat
EXEC SQL FETCH Cust_Assigns
INTO (:custnum, :salesnum);
until :custnum=:cnum;
EXEC SQL CLOSE CURSOR Cust_assigns;
EXEC SQL UPDATE Orders
SET snum=:salesnum
WHERE CURRENT OF Wrong_Orders;
end; {If SQLCODE=0}
end; { While SQLCODE . . . do }
EXEC SQL CLOSE CURSOR Wrong_Orders;
* end; { main program }
EXEC SQL BEGIN DECLARE SECTION;
SQLCODE integer;
newcity packed array[1. .12] of char;
commnull boolean;
citynull boolean;
response char;
EXEC SQL END DECLARE SECTION;
EXEC SQL DECLARE CURSOR Salesperson AS
SELECT * FROM SALESPEOPLE;
begln { main program }
EXEC SQL OPEN CURSOR Salesperson;
EXEC SQL FETCH Salesperson
INTO (:snum, :sname, :city:i_cit, :comm:i_com);
{Выборка первой строки}
while SQLCODE=O do
{Пока эти строки в таблице Продавцов.}
begin
if i_com < O then commnull:=true;
if i_cit < O then citynull:=true;
{ Установить логические флаги которые могут показать NULLS.}
if citynull then
begin
write ('Нет текущего значения city для продавца ',
snum, ' Хотите предоставить хотя бы одно? (Y/N)');
{Подсказка покажет значение city состоящее из NULL значений.}
read (ответ);
{Ответ может быть сделан позже.}
end {если конечно - citynull}
else { не citynull }
begin
if not commnull then