Понимание SQL
Шрифт:
#1 - не модифицируемый, потому что он использует DISTINCT.
#2 - не модифицируемый, потому что он использует обьединение, агрегатную функцию, и GROUP BY.
* #3 - не модифицируемый, потому что он основывается на #1, который сам по себе не модифицируемый.
CREATE VIEW Commissions AS SELECT snum, comm
FROM Salespeople WHERE comm BETWEEN .10 AND .20
* WITH CHECK OPTION;
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.
* GRANT UPDATE (rating) ON Customers TO Janet;
* GRANT SELECT ON Orders TO Stephen WITH GRANT OPTION;
* REVOKE INSERT ON Salespeople FROM Claire;
Шаг 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;
Шаг 1:
CREATE VIEW Janetsview
AS SELECT * FROM Customers
WHERE rating=(SELECT MIN (rating) FROM Customers);
Шаг 2:
* GRANT SELECT ON Janetsview TO Janet;
Глава 23.
* CREATE DBSPACE Myspace (pctindex 15, pctfree 40);
* CREATE SYNONYM Orders FOR Diane.Orders;
*
* Блокировка взаимоисключающего доступа.
* Толко чтение
Глава 24.
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 в вышеупомянутой команде - строго обязательны. Они представлены просто для понимания.
SELECT tname, synowner, COUNT (ALL synonym)
* FROM SYTEMSYNONS GROUP BY tname, synowner;
. 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.
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; { основная программа }
Для данной программы которую я использовал, решение будет состоять в том, чтобы просто включить поле 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;