Online Documentation Server
 ПОИСК
ods.com.ua Web
 КАТЕГОРИИ
Home
Programming
Net technology
Unixes
Security
RFC, HOWTO
Web technology
Data bases
Other docs

 

 ПОДПИСКА

 О КОПИРАЙТАХ
Вся предоставленная на этом сервере информация собрана нами из разных источников. Если Вам кажется, что публикация каких-то документов нарушает чьи-либо авторские права, сообщите нам об этом.




Приложение A


ОТВЕТЫ ДЛЯ УПРАЖНЕНИЙ

Глава 1

  1. cnum
  2. rating
  3. Другим словом для строки является - запись. Другим словом для столбца является - поле.
  4. Потому что строки, по определению, находятся без какого либо определенного упорядочения.

Глава 2

  1. Символ ( или текст ) и номер
  2. Нет
  3. Язык Манипулирования Данными (ЯЗЫК DML)
  4. Это слово в SQL имеет специальное учебное значение.

Глава 3

  1. SELECT onum, amt, odate
    FROM Orders;
    
  2. SELECT *
     FROM Customers
     WHERE snum = 1001;
    
  3. SELECT city, sname, snum, comm
    FROM Salespeople;
    
  4. SELECT rating, cname
     FROM Customers
     WHERE city = 'SanJose';
    
  5. SELECT DISTINCT snum
     FROM Orders;
    

Глава 4

1. SELECT * FROM Orders WHERE amt > 1000;

2. SELECT sname, city
 FROM Salespeople
 WHERE city = 'London'
   AND comm > .10;

3. SELECT *
 FROM Customers
 WHERE rating > 100
   OR city = 'Rome';

 или
  SELECT *
FROM Customers
WHERE NOT rating < = 100
  OR city = 'Rome';
 или
  SELECT *
FROM Customers
WHERE NOT (rating < = 100
  AND city < > 'Rome');

Могут быть еще другие решения.


4. onum      amt   odate    cnum  snum

   3001      18.69  10/03/1990  2008  1007

   3003     767.19  10/03/1990  2001  1001

   3005    5160.45  10/03/1990  2003  1002

   3009    1713.23  10/04/1990  2002  1003

   3007      75.75  10/04/1990  2004  1002

   3008    4723.00  10/05/1990  2006  1001

   3010    1309.95  10/06/1990  2004  1002

   3011    9891.88  10/06/1990  2006  1001

5. onum    amt      odate   cnum  snum

   3001    18.69    10/03/1990  2008  1007

   3003    767.19   10/03/1990  2001  1001


  onum    amt    odate     cnum snum

  3006  1098.16  10/03/1990   2008  1007

  3009  1713.23  10/04/1990   2002  1003

  3007  75.75    10/04/1990   2004  1002

  3008  4723.00  10/05/1990   2006  1001

  3010  1309.95  10/06/1990   2004  1002

  3011  9891.88  10/06/1990   2006  1001

6. SELECT *
 FROM Salespeople;


Глава 5

1. SELECT * FROM Orders WHERE odate IN (10/03/1990,10/04/1990); и SELECT * FROM Orders WHERE odate BETWEEN 10/03/1990 AND 10/04,1990; 2. SELECT * FROM Customers WHERE snum IN (1001,1004); 3. SELECT * FROM Customers WHERE cname BETWEEN 'A' AND 'H'; ПРИМЕЧАНИЕ: ВЫ ASCII базовой системе Hoffman не будет выве ден из-за конечных пробелов после H. По той же самой причине вторая граница не может быть G, поскольку она не выведет имена Giovanni и Grass. G может использоваться в сопровождении с Z, так чтобы следовать за другими символами в алфавитном порядке, а не предшествовать им, как это делают пробелы. 4. SELECT * FROM Customers WHERE cname LIKE 'C%'; 5. SELECT * FROM Orders WHERE amt < > O AND (amt IS NOT NULL); или SELECT * FROM Orders WHERE NOT (amt = O OR amt IS NULL);

Глава 6

1. SELECT COUNT(*) FROM Orders WHERE odate = 10/03/1990; 2. SELECT COUNT (DISTINCT city) FROM Customers; 3. SELECT cnum, MIN (amt) FROM Orders GROUP BY cnum; 4 SELECT MIN (cname) FROM Customers WHERE cname LIKE 'G%'; 5. SELECT city, MAX (rating) FROM Customers GROUP BY city; 6 SELECT odate, count (DISTINCT snum FROM Orders GROUP BY odate;

Глава 7

1. SELECT onum, snum, amt * .12 FROM Orders; 2. SELECT 'For the city ', city, ', the highest rating is ', ", MAX (rating) FROM Customers GROUP BY city; 3 SELECT rating, cname, cnum FROM Customers ORDER BY rating DESC; 4. SELECT odate, SUM (amt) FROM Orders GROUP BY odate ORDER BY 2 DESC;

Глава 8

1. SELECT onum, cname FROM Orders, Customers WHERE Customers.cnum = Orders.cnum; 2. SELECT onum, cname, sname FROM Orders, Customers, Salespeople WHERE Customers.cnum = Orders.cnum AND Salespeople.snum = Orders.snum; 3. SELECT cname, sname, comm FROM Salespeople, Customers WHERE Salespeople.snum = Customers.snum AND comm * .12; 4. SELECT onum, comm * amt FROM Salespeople, Orders, Customers WHERE rating > 100 AND Orders.cnum = Customers.cnum AND Orders.snum = Salespeople.snum;

Глава 9

1. SELECT first.sname, second.sname FROM Salespeople first, Salespeople second WHERE first.city = second.city AND first.sname < second.sname; Псевдонимам нет необходимости иметь именно такие имена. 2. SELECT cname, first.onum, second.onum FROM Orders first, Orders second, Customers WHERE first.cnum = second.cnum AND first.cnum = Customers.cnum AND first.onum < second.onum; Ваш вывод может иметь некоторые отличи, но в вашем ответе все логические компоненты должны быть такими же. 3. SELECT a.cname, a.city FROM Customers a, Customers b WHERE a.rating = b.rating AND b.cnum = 2001;

Глава 10

1. SELECT * FROM Orders WHERE cnum = (SELECT cnum FROM Customers WHERE cname = 'Cisneros'); или SELECT * FROM Orders WHERE cnum IN (SELECT cnum FROM Customers WHERE cname = 'Cisneros'); 2. SELECT DISTINCT cname, rating FROM Customers, Orders WHERE amt > (SELECT AVG (amt) FROM Orders) AND Orders.cnum = Customers.cnum; 3 SELECT snum, SUM (amt) FROM Orders GROUP BY snum HAVING SUM (amt) > (SELECT MAX (amt) FROM Orders);

Глава 11

1. SELECT cnum, cname FROM Customers outer WHERE rating = (SELECT MAX (rating) FROM Customers inner WHERE inner.city = outer.city); 2. Решение с помощью соотнесенного подзапроса: SELECT snum, sname FROM Salespeople main WHERE city IN (SELECT city FROM Customers inner WHERE inner.snum < > main.snum); Решение с помощью объединения: SELECT DISTINCT first.snum, sname FROM Salespeople first, Customers second WHERE first.city = second.city AND first.snum < > second.snum; Соотнесенный подзапрос находит всех заказчиков, не обслуживаемых данным продавцом, и выясняет: живет ли кто-нибудь из их в его городе. Решение с помощью объединения является более простым и более инту- итивным. Оно находит случаи где пол city совпадают, а пол snums нет. Следовательно объединение является более изящным решением для этой проблемы, чем то которое мы исследовали до этого. Имеется еще более изящное решение с помощью подзапроса, с которым Вы столкнетесь позже.

Глава 12

1. SELECT * FROM Salespeople first WHERE EXISTS (SELECT * FROM Customers second WHERE first.snum = second.snum AND rating = 300); 2. SELECT a.snum, sname, a.city, comm FROM Salespeople a, Customers b WHERE a.snum = b.snum AND b.rating = 300; 3. SELECT * FROM Salespeople a WHERE EXISTS (SELECT * FROM Customers b WHERE b.city = a.city AND a.snum < > b.snum); 4. SELECT * FROM Customers a WHERE EXISTS (SELECT * FROM Orders b WHERE a.snum = b.snum AND a.cnum < > b.cnum)

Глава 13

1. SELECT * FROM Customers WHERE rating > = ANY (SELECT rating FROM Customers WHERE snum = 1002); 2. cnum cname city rating snum 2002 Giovanni Rome 200 1003 2003 Liu San Jose 200 1002 2004 Grass Berlin 300 1002 2008 Cisneros SanJose 300 1007 3. SELECT * FROM Salespeople WHERE city < > ALL (SELECT city FROM Customers); или SELECT * FROM Salespeople WHERE NOT city = ANY (SELECT city FROM Customers); 4. SELECT * FROM Orders WHERE amt > ALL (SELECT amt FROM Orders a, Customers b WHERE a.cnum = b.cnum AND b.city = 'London'); 5. SELECT * FROM Orders WHERE amt > (SELECT MAX (amt) FROM Orders a, Customers b WHERE a.cnum = b.cnum AND b.city = 'London');

Глава 14

1. SELECT cname, city, rating, 'High Rating' FROM Customers WHERE rating > = 200 UNION SELECT cname, city, rating, ' Low Ratlng' FROM Customers WHERE rating < 200; или SELECT cname, city, rating, 'High Rating' FROM Customers WHERE rating > = 200 UNION SELECT cname, city, rating, ' Low Rating' FROM Customers WHERE NOT rating > = 200; Различие между этими двум предложениями, в форме второго предиката. Обратите внимание что, в обоих случаях, строка "Low Rating" имеет в начале дополнительный пробел для того чтобы совпадать со строкой "High Rating" по длине. 2. SELECT cnum, cname FROM Customers a WHERE 1 < (SELECT COUNT (-) FROM Orders b WHERE a.cnum = b.cnum) UNION SELECT snum, sname FROM Salespeople a WHERE 1 < (SELECT COUNT (*) FROM Orders b WHERE a.snum = b.snum) ORDER BY 2; 3. SELECT snum FROM Salespeople WHERE city = 'San Jose' UNION (SELECT cnum FROM Customers WHERE city = 'San Jose' UNION ALL SELECT onum FROM Orders WHERE odate = 10/03/1990);

Глава 15

1. INSERT INTO Salespeople (city, cname, comm, cnum) VALUES ('San Jose', 'Blanco', NULL, 1100); 2. DELETE FROM Orders WHERE cnum = 2006; 3. UPDATE Customers SET rating = rating + 100 WHERE city = 'Rome'; 4. UPDATE Customers SET snum = 1004 WHERE snum = 1002;

Глава 16

1. INSERT INTO Multicust SELECT * FROM Salespeople WHERE 1 < (SELECT COUNT (*) FROM Customers WHERE Customers.snum = Salespeople.snum); 2. DELETE FROM Customers WHERE NOT EXISTS (SELECT * FROM Orders WHERE cnum = Customers.cnum); 3. UPDATE Salespeople SET comm = comm + (comm * .2) WHERE 3000 < (SELECT SUM (amt) FROM Orders WHERE snum = Salespeople.snum); В более сложный вариант этой команды можно было бы вставить проверку чтобы убедиться, что значения комиссионных не превышают 1.0 ( 100 % ): UPDATE Salespeople SET comm = comm + (comm * .2) WHERE 3000 < (SELECT SUM (amt) FROM Orders WHERE snum = Salespeople.snum) AND comm + (comm * .2) < 1.0; Эти проблемы могут иметь другие, такие же хорошие решения.

Глава 17

1. CREATE TABLE Customers (cnum integer, cname char(10), city char(10), rating integer, snum integer); 2. CREATE INDEX Datesearch ON Orders(odate); ( Все индексные имена используемые в этих ответах - произвольные. ) 3. CREATE UNIQUE INDEX Onumkey ON Orders(onum); 4. CREATE INDEX Mydate ON Orders(snum, odate); 5. CREATE UNIQUE INDEX Combination ON Customers(snum, rating);

Глава 18

1. CREATE TABLE Orders (onum integer NOT NULL PRIMARY KEY, amt decimal, odate date NOT NULL, cnum integer NOT NULL, snum integer NOT NULL, UNIOUE (snum, cnum)); или CREATE TABLE Orders (onum integer NOT NULL UNIQUE, amt decimal, odate date NOT NULL, cnum integer NOT NULL, snum integer NOT NULL, UNIQUE (snum, cnum)); Первое решение предпочтительнее. 2. CREATE TABLE Salespeople (snum integer NOT NULL PRIMARY KEY, sname char(15) CHECK (sname BETWEEN 'AA' AND 'MZ'), city char(15), comm decimal NOT NULL DEFAULT = .10); 3. CREATE TABLE Orders (onum integer NOT NULL, amt decimal, odate date, cnum integer NOT NULL, snum integer NOT NULL, CHECK ((cnum > snum) AND (onum > cnum)));

Глава 19

1. CREATE TABLE Cityorders (onum integer NOT NULL PRIMARY KEY, amt decimal, cnum integer, snum integer, city char (15), FOREIGN KEY (onum, amt, snum) REFERENCES Orders (onum, amt, snum), FOREIGN KEY (cnum, city) REFERENCES Customers (cnum, city) ); 2. CREATE TABLE Orders (onum integer NOT NULL, amt decimal, odate date, cnum integer NOT NULL, snum integer, prev integer, UNIQUE (cnum, onum), FOREIGN KEY (cnum, prev) REFERENCES Orders (cnum,onum) );9

Глава 20

1. CREATE VIEW Highratings AS SELECT * FROM Customers WHERE rating = (SELECT MAX (rating) FROM Customers); 2. CREATE VIEW Citynumber AS SELECT city, COUNT (DISTINCT snum) FROM Salespeople GROUP BY city; 3. CREATE VIEW Nameorders AS SELECT sname, AVG (amt), SUM (amt) FROM Salespeople, Orders WHERE Salespeople.snum = Orders.snum GROUP BY sname; 4 CREATE VIEW Multcustomers AS SELECT * FROM Salespeople a WHERE 1 < (SELECT COUNT (*) FROM Customers b WHERE a.snum = b.snum);

Глава 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)');
    
  4. Обратите Внимание: Продавец не назначенный в данное время в определенный город, не будет иметь изменений комиссионных при определении находится ли он в Лондоне.
    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; {основной программы}
    


With any suggestions or questions please feel free to contact us