Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
122
Добавлен:
22.03.2015
Размер:
2.28 Mб
Скачать

Глава 21

1. #1 - не модифицируемый, потому что он использует DISTINCT.

#2 - не модифицируемый, потому что он использует обьединение, агре-

гатную функцию, и GROUP BY.

#3 - не модифицируемый, потому что он основывается на #1, который

сам по себе не модифицируемый.

2. CREATE VIEW Commissions

AS SELECT snum, comm

FROM Salespeople

WHERE comm BETWEEN .10 AND .20

WITH CHECK OPTION;

3. CREATE TABLE Orders

(onum integer NOT NULL PRIMARY KEY,

amt decimal,

odate date DEFAULT VALUE = CURDATE,

snum integer,

cnum integer);

CREATE VIEW Entryorders

AS SELECT onum, amt, snum, cnum

FROM Orders;

Глава 22

1. GRANT UPDATE (rating) ON Customers TO Janet;

2. GRANT SELECT ON Orders TO Stephen WITH GRANT OPTION;

3. REVOKE INSERT ON Salespeople FROM Claire;

4. Шаг 1: CREATE VIEW Jerrysview

AS SELECT *

FROM Customers

WHERE rating BETWEEN 100 AND 500

WITH CHECK OPTION;

Шаг 2: GRANT INSERT, UPDATE ON Jerrysview TO Jerry;

5. Шаг 1: CREATE VIEW Janetsview

AS SELECT *

FROM Customers

WHERE rating =

(SELECT MIN (rating)

FROM Customers);

Шаг 2: GRANT SELECT ON Janetsview TO Janet;

Глава 23

1. CREATE DBSPACE Myspace

(pctindex 15,

pctfree 40);

2. CREATE SYNONYM Orders FOR Diane.Orders;

3. Они должны быть откатаны обратно назад.

4. Блокировка взаимоисключающего доступа.

5. Толко чтение

Глава 24

1. SELECT a.tname, a.owner, b.cname, b.datatype

FROM SYSTEMCATOLOG a, SYSTEMCOLUMNS b

WHERE a.tname = b.tname

AND a.owner = b.owner

AND a.numcolumns > 4;

Обратите Внимание: из-за того что большинство имен столбца объединяе-

мых таблиц - различны, не все из используемых псевдонимов a и b в вы-

шеупомянутой команде - строго обязательны. Они представлены просто для

понимания.

2. SELECT tname, synowner, COUNT (ALL synonym)

FROM SYTEMSYNONS

GROUP BY tname, synowner;

3. SELECT COUNT (*)

FROM SYSTEMCATALOG a

WHERE numcolumns/2 <

(SELECT COUNT (DISTINCT cnumber)

FROM SYSTEMINDEXES b

WHERE a.owner = b.tabowner

AND a.tname = b.tname);

Глава 25

1. EXEC SQL BEGIN DECLARE SECTION;

SQLCODE:integer;

{требуемый всегда}

cnum integer;

snum integer;

custnum: integer;

salesnum: integer;

EXEC SQL END DECLARE SECTION;

EXEC SQL DECLARE Wrong_Orders AS CURSOR FOR

SELECT cnum, snum

FROM Orders a

WHERE snum < >

(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; { основная программа }

2. Для данной программы которую я использовал, решение будет состоять

в том, чтобы просто включить поле 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 }

3. 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

{ Чтобы выполнять сравнение и операции только для не-NULL значений

связи }

begin

if city = 'London' then comm: = comm * .02 * .02

else comm: = comm + .02;

end;

{Даже если значение и не - commnull, begin и end здесь для ясности.}

write ('Текущий city для продавца',

snum, 'есть', city,

Хотите его изменить? (Y/N)');

3. Обратите Внимание: Продавец не назначеный в данное время в опреде-

ленный город, не будет иметь изменений комиссионых при определении

находятся ли он в Лондоне.

read (ответ);

{Ответ теперь имеет значение независимо от того что

citynull - верен или неверен.}

end; {иначе не citynull}

if response = 'Y' then

begin

write ('Введите новое значение city:');

read (newcity);

if not commnull then

{Эта операция может быть выполнена только для не-NULL

значений. }

case newcity of:

begin

'Barcelona':comm:= comm + .01,

'San Jose': comm: = comm *.01

end; {случно и если не commnull}

EXEC SQL UPDATE Salespeople

SET city = :newcity, comm = :comm:i_com

WHERE CURRENT OF Salesperson;

{Переменная индикатора может поместить NULL значение в поле

comm если так назначено.}

end; { Если ответ = 'Y', или если ответ < > 'Y',

изменений не будет. }

EXEC SQL FETCH Salesperson

INTO (:snum, :sname, :city:i_clt,

:comm:l_com);

{выборка следующей строки}

end; {если SQLCODE = 0}

EXEC SQL CLOSE CURSOR Salesperson;

end; {основной программы}

Соседние файлы в папке Базы данных