On-Line Библиотека www.XServer.ru - учебники, книги, статьи, документация, нормативная литература.
       Главная         В избранное         Контакты        Карта сайта   
    Навигация XServer.ru








 

Понимание SQL.

                            Приложение  C
                            ДДДДДДДДДДДДД
              НЕКОТОРЫЕ ОБЩИЕ НЕСТАНДАРТНЫЕ СРЕДСТВА SQL

  ИМЕЕТСЯ РЯД ОСОБЕННОСТЕЙ ЯЗЫКА SQL которые пока  не  определены  как
часть  стандарта  ANSI или стандарта ISO (Международная Организация По
Стандартизации),  и являются общими для многочисленных реализаций, так
как  они  были получены для практического использования.  Это дополни-
тельные элементы чисел этих особенностей. Конечно, эти особенности ме-
няются от программы к программе,  и их обсуждение предназначено только
чтобы показать некоторые общие подходы к ним.

            ==============  ТИПЫ ДАННЫХ  =================

  Типы данных поддерживаемые стандартом SQL,  собраны в Приложении  B.
Это колличество для CHARACTER и разнообразие числовых типов.  Реализа-
ция их может, фактически, быть значительно сложнее чем показано в тер-
минах типов, которые они фактически могут использовать. Мы будем здесь
обсуждать ряд таких нестандартных типов данных.

                           ТИПЫ DATE И TIME

  Как упомянуто в Главе 2, тип данных DATE широко поддерживается, даже
если он не часть стандарта.  Мы использовали ранее в нашей таблице По-
рядков,  этот тип использующий формат mm/dd/yyyy. Это стандартный фор-
мат IBM в США. Разумеется возможны и другие форматы, и программные ре-
ализации часто поддерживают ряд форматов,  позволяя вам  выбирать  тот
который лучше для вас подходит. Реализация которая предлагает эту осо-
бенность должна быть способна преобразовывать дату  одного  формата  в
другой - автоматически.
  Имеются несколько основных форматов даты с которыми вы можете сталк-
нуться:

  Стандарт               Формат           Пример
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Международная
Организация По
Стандартизации 
(ISO)                   yyyy-mm-dd       1990-10-31
Японский
Индустриальный
Стандарт (JIS)          yyyy-mm-dd       1990-10-31
IBM Европейский
Стандарт (EUR)          dd.mm.yyyy       10.31.1990

  Наличие специального  типа определяемого для даты,  дает возможность
выполнять арифметические операция с датами. Например, вы можете добав-
лять число дней к дате и получать другую дату,  в программе, самостоя-
тельно следящей за числом дней в месяцах,  високосными годами,  и  так
далее. Даты могут также сравниваться; например фраза, дата A < дата B,
означает, что дата A предшествует дате B по времени.
  Кроме даты,  большое  количество программ определяют специальный тип
для времени,  который может также быть представлен  в  ряде  форматов,
включая следующие:

Стандарт                        Формат          Пример
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
МЕЖДУНАРОДНАЯ
ОРГАНИЗАЦИЯ ПО
СТАНДАРТИЗАЦИИ (ISO)           hh-mm-ss         21.04.37
Японский
Индустриальный
Стандарт (JIS )                hh-mm-ss         21.04.37
IBM Европейский
Стандарт                       hh-mm-ss         21.04.37
IBM USA Стандарт               hh.mm AM/PM      9.04 PM
   (USA)

  Время может добавляться или сравниваться точно  также  как  дата,  с
коррекцией числа секунд в минутах или часах автоматически. Кроме того,
специально встроенные константы указывающие текущую дату или  время  (
CURDATE  или  CURTIME ) являются общими.  Они похожи на константу USER
(Пользователь) в которой их значение будет непрерывно меняться.
  Можете ли вы включать время и дату в одно поле ?  Некоторые реализа-
ции определяют тип DATE достаточно точно,  чтобы включать туда  еще  и
TIME.
  В качестве альтернативы,  третий обобщающий  тип,  TIMESTAMP,  может
быть определен как комбинация этих двух.

                        ТИПЫ ТЕКСТОВОЙ СТРОКИ

  ANSI поддерживает  только  один тип чтобы представлять текст.  Это -
тип CHAR. Любое поле такого типа должно иметь определенную длину. Если
строка вставляемая в поле меньше чем длина поля,  она дополняется про-
белами; строка не может быть длиннее чем длина поля.
  Хотя и  достаточно  удобное,  это определение все же имеет некоторые
ограничения для пользователя.  Например,  символьные поля должны иметь
одинаковую длинну чтобы можно было выполнить команду UNION.  Большинс-
тво реализаций,  поддерживают строки переменной длины для типов данных
VARCHAR  и  LONG  VARCHAR( или просто LONG).  В то время как поле типа
CHAR всегда может распределить память для максимального числа символов
которое  может сохраняться в поле,  поле VARCHAR при любом колличестве
символов,  может распределить только  определенное  количество  памяти
чтобы сохранить фактическое содержание поля, хотя SQL может установить
снаружи, некоторое дополнительное пространство памяти чтобы следить за
текущей длиной поля.
  Поле VARCHAR может быть любой длинны включая реализационно-определя-
емый  максимум.  Этот  максимум может меняться от 254 до 2048 символов
для VARCHAR,  и до 16000 символов для LONG.  LONG обычно  используется
для  текста пояснительного характера или для данных,  которые не могут
легко сжиматься в простые значения полей; VARCHAR может использоваться
для любой текстовой строки чья длина может меняться.  Между прочим, не
всегда хорошо использовать VARCHAR вместо CHAR. Извлечение и модифици-
рование полей VARCHAR - более сложный, и следовательно более медленный
процесс,  чем извлечение и модифицирование полей CHAR. Кроме того, не-
которое количество памяти VARCHAR, остается всегда неиспользованной (в
резерве) для гарантии вмещения всей длины строки.  Вы должны просчиты-
вать,  насколько значения полей могут меняться по длине, а также, спо-
собны ли они к объединению с другими полями, перед тем как решить, ис-
пользовать CHAR или VARCHAR. Часто, тип LONG используется для сохране-
ния двоичных данных.  Естественно,  что использование  размера  такого
"неуклюжего" поля будет ограничивать оперативность SQL.  Проконсульти-
руйтесь с вашим руководством.

            =============  КОМАНДА FORMAT  ===============

  Как мы подчеркивали в Главе 7,  процесс вывода выполняемого в  стан-
дарте SQL - ограничен.  Хотя большинство реализаций включают SQL в па-
кеты,  имеющие другие средства для управления этой функцией, некоторые
реализации также используют команду типа FORMAT внутри SQL чтобы навя-
зывать выводу запроса, определенные формы, структуры, или ограничения.
Среди возможных функций команды FORMAT - существуют такие:

* определение ширины столбцов ( при печати ).
* определение представления NULL значений.
* обеспечение (новых) заголовков для столбцов.
* обеспечение заголовков внизу или вверху страниц выводимых на печать.
* навязывает присвоение или изменение форматам полей содержащих значе-
  ния даты, времени или денежной суммы.
* вычисляет общие и промежуточные суммы не исключая возможности  обоб-
  щения поля, как это делает например SUM. ( Альтернативным подходом к
  этой проблеме в некоторых программах является предложение COMPUTE. )

  Команда FORMAT может вводиться сразу перед или сразу после запроса к
которому она применяется,  в зависимости от реализации.  Одна  команда
FORMAT  обычно  может применяться только к одному запросу,  хотя любое
число команд FORMAT может применяться к одному и тому же запросу.  Вот
некоторые примеры команды FORMAT:

       FORMAT NULL '_ _ _ _ _ _ _';
       FORMAT BTITLE 'Orders Grouped by Salesperson';
       FORMAT EXCLUDE (2, 3);

  Первая из  их  значения  NULL представляеть в виде ю _ _ _ _ _ _ _ ю
при выводе на печать;  вторая вставляет заголовок 'Orders  Grouped  by
Salesperson' в нижнюю часть каждой страницы; третья исключает второй и
третий столбцы из вывода предыдущего запроса. Вы могли бы использовать
последнюю из их если вы выбираете конкретные столбцы,  чтобы использо-
вать их в предложении ORDER BY,  в вашем  выводе.  Так  как  указанные
функции  команды  FORMAT  могут выполняться по разному,  весь набор их
приложений не может быть здесь показан.
  Имеются другие  команды  которые могут использоваться для выполнения
тех же функций. Команда SET подобна команде FORMAT; она является вари-
антом или дополнением к команде,  которая применяется во всех запросах
текущего сеанса пользователя а не просто в одиночном запросе. В следу-
ющей реализации, команда FORMAT начинается ключевым словом COLUMN сле-
дующим образом:

         COLUMN odate FORMAT dd-mon-yy;

что навязывает формат типа - 10-Oct-90 в поле  даты  использующемся  в
выводе  запроса  на  печать.  Предложение  COMPUTE,  упомянутое ранее,
вставляется в запрос, следующим образом:

        SELECT odate, amt
           FROM Orders
           WHERE snum = 1001
           COMPUTE SUM (amt);

Оно выводит  все порядки продавца Peel,  с датой и суммой приобретения
по каждой дате, а в конце, общую сумму приобретений.
  Другая реализация выводит промежуточные суммы приобретений используя
COMPUTE в качестве команды. Сначала, она определяет разбивку

            BREAK ON odate;

вывода вышеупомянутого запроса на страницы - сгруппировав их по датам,
поэтому все значения odate в каждой группе - одинаковые.  Затем вы мо-
жете ввести следующее предложение:

           COMPUTE SUM OF amt ON odate;

Столбец в предложении ON,  предварительно,  должен быть использован  в
команде BREAK.

            ================  ФУНКЦИИ ====================

  Для SQL в стандарте ANSI, вы можете применять агрегатные функции для
столбцов или использовать их значения в  скалярных  выражениях,  таких
например как - comm * 100.  Имеется много других полезных функций, ко-
торые вы, вероятно встречали на практике.
  Имеется список некоторых общих функций SQL отличающихся от стандарт-
ных агрегатов.  Они могут использоваться в предложениях SELECT  запро-
сов,  точно так же как агрегатные функции,  но эти функции выполняются
для одиночных значениях а не групповых. В следующем списке они класси-
фицированны согласно типам данных с которыми они выполняются. Если нет
примечаний, то переменные в этом списке стандартизованы для любого вы-
ражения значений соответствующего типа, которые могут быть использова-
ны в предложении SELECT:

                        МАТЕМАТИЧЕСКИЕ ФУНКЦИИ

  Эти функции применяются для чисел.

    ФУНКЦИЯ        ЗНАЧЕНИЕ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
    ABX(X)        Абсолютное значение из X ( преобразование
                  отрицательного или положительного значений в
                  положительное )
    CEIL (X)      X - является десятичным значением которое будет
                  округляться сверху.
    FLOOR (X)     X - является десятичным значением которое будет
                  округляться снизу.
    GREATEST(X,Y) Возвращает большее из двух значений.
    LEAST(X,Y)    Возвращает меньшее из двух значений.
    MOD(X,Y)      Возвращает остаток от деления X на Y.
    POWER(X,Y)    Возвращает значение X в степени Y.
    ROUND(X,Y)    Цикл от X до десятичного Y.
                  Если Y отсутствует, цикл до целого числа.
    SING(X)       Возвращает минус если X < 0, или плюс если X > 0.
    SQRT (X)      Возвращает квадратный корень из X.

                          СИМВОЛЬНЫЕ ФУНКЦИИ

  Эти функции могут быть применены для строк текста,  либо из столбцов
текстовых типов данных,  либо из строк литерных текстов, или же комби-
нация из этих двух.

   ФУНКЦИЯ                 ЗНАЧЕНИЕ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД

   LEFT(,X)    Возвращает крайние левые(старшие) символы X 
                       из строки.
   RICHT(,X)   Возвращает символы X младшего разряда из
                       строки
   ASCII()     Возвращает код ASCII которым представляется
                       строка в памяти компьютера.
   CHR()    Возвращает принтерные символы кода ASCII.
   VALUE()     Возвращает математическое значение для
                       строки. Считается что строка имеет тип CHAR
                       или VARCHAR, но состоит из чисел.
                       VALUE('3') произведет число 3 типа INTEGER.
   UPPER()     Преобразует все символы строки в символы
                       верхнего регистра.
   LOWER()     Преобразует все символы строки в символы
                       нижнего регистра.
   INlTCAP()   Преобразует символы строки в заглавные
                       буквы. В некоторых реализациях может иметь
                       название - PROPER.
   LENGTH()    Возвращает число символов в строке.
   ||  Объединяет две строки в выводе, так чтобы
                       после первой немедленно следовала вторая.
                       (значек || называется оператором сцепления).
   LPAD(,X,'*')   Дополняет строку слева звездочками
                       '*', или любым другим указанным
                       символом, с колличестве, определяемом X.
   RPAD(,X, ") То же самое что и LPAD, за исключением
                       того, что дополнение делается справа.
   SUBSTR(,X,Y)   Извлекает Y символов из строки начиная
                       с позиции X.
                               
                        ФУНКЦИИ ДАТЫ И ВРЕМЕНИ

  Эти функции выполняются только для допустимых значений даты или вре-
мени.

      ФУНКЦИЯ                    ЗНАЧЕНИЕ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
    DAY()         Извлекает день месяца из даты.
                        Подобные же функции существуют
                        для MONTH(МЕСЯЦ), YEAR(ГОД),
                        HOUR(ЧАСЫ), SECOND(СЕКУНДЫ)
                        и так далее.
    WEEKDAY()     Извлекает день недели из даты.

                            ДРУГИЕ ФУНКЦИИ

  Эта функция может быть применена к любому типу данных.

      ФУНКЦИЯ                    ЗНАЧЕНИЕ
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
NVL(,)     NVL (NULL Значение) будет меняться
                          на значение  каждое NULL значе-
                          ние найденое в столбце . Если по-
                          лученное значение  не =NULL,
                          NVL ничего не делает.

               ========== INTERSECT И MINUS ==========
                        
  Команда UNION,  как  вы уже видели в Главе 14,  может объединить два
запроса, обьединив их вывод в один. Два других обычно имеющихся спосо-
ба  объединения  отдельных  запросов - это INTERSECT(Плюс) и MINUS(Ми-
нус). INTERSECT выводит только строки произведенные обоими перекресны-
ми запросами, в то время как MINUS выводит строки которые производятся
одним запросом, но не другим. Следовательно, следующие два запроса

      SELECT *
         FROM Salespeople
         WHERE city = 'London'

         INTERSECT

      SELECT *
         FROM Salespeople
         WHERE 'London' IN
            (SELECT city
                FROM Customers
                WHERE Customers.snum =
                 Salespeople.snum);

выведут строки произведенные обоими запросами, производящими всех про-
давцов в Лондоне которые имели по крайней мере одного заказчика разме-
щенного там также. С другой стороны, запрос

      SELECT *
         FROM Salespeople
         WHERE city = 'London'

         MINUS

      SELECT *
         FROM Salespeople
         WHERE 'London' IN
            (SELECT sity
                FROM Customers
                WHERE Customers.snum =
                 Salespeople.snum);

удалит строки выбранные вторым запросом из вывода первого, и таким об-
разом  будут  выводены все продавцы в Лондоне которые не имели там за-
казчиков. MINUS иногда еще называют DIFFERENCE (ОТЛИЧИЕ)

                            АВТОМАТИЧЕСКИЕ 
              ========== ВНЕШНИЕ ОБЬЕДИНЕНИЯ ===========

  В Главе  14,  мы  обсуждали внешнее обьединение и показывали вам как
выполнять его используя команду UNION. Некоторые программы базы данных
имеют более непосредственный способ выполнения внешних обьединений.  В
некоторых реализациях,  вводимый знак " + " после предиката, может вы-
водить строки которые удовлетворяют условию также как и строки которые
ему не удовлетворяют.  В условии предиката может содержаться поле сов-
падающее  для обеих таблиц,  и NULL значения будут вставлены там,  где
такого совпадения не будет найдено.  Например,  предположим вы  хотите
видеть  ваших  продавцов и соответствующих им заказчиков,  не исключая
тех продавцов которым не назначено ни одного заказчика (  хотя  такого
нет в наших типовых таблицах, но в действительности это возможно ) :

        SELECT a.snum, sname, cname
           FROM Salespeople a, Customers b
           WHEREa.snum = b.snum(+);

Это является эквивалентом следующего объединения (UNION):

        SELECT a.snum, sname, cname
           FROM Salespeople a, Customers b
           WHERE a.snum = b.snum

           UNION

        SELECT snum, sname, '_ _ _ _ _ _ _ _ _ _'
           FROM Salespeople
           WHERE snum NOT IN
              (SELECT snum
                  FROM Customers);

Мы считаем что подчеркивания будут отображены NULL значениями( см. ко-
манду FORMAT ранее в этом приложении где описывалось отображение  NULL
значениями).

            ========== ОТСЛЕЖИВАНИЕ ДЕЙСТВИЙ =============

  Ваша SQL  реализация  - достаточна хороша,  если она доступна многим
пользователями,  чтобы обеспечивать для них некий способ  слежения  за
действиями выполняемыми в базе данных. Имеются две основные формы что-
бы делать это:

  Journaling(Протоколирование) и  Auditing(Ревизия).

  Эти формы отличаются по назначению.  Journaling,  пименяется с целью
защиты ваших данных,  при разрушении вашей системы. Сначала Вы исполь-
зуете реализационно-зависимую процедуру чтобы архивировать текущее со-
держание вашей базы данных, поэтому копия ее содержания где-нибудь бу-
дет сохранена.  Затем вы просматриваете протокол изменений сделанных в
базе данных.  Он сохраняется в некоторой области памяти, но не в глав-
ной памяти базы данных а желательно на отдельном устройстве,  и содер-
жит  список  всех команд которые произвели изменения в структуре или в
содержании базы данных.  Если у вас вдруг появились проблемы и текущее
содержание вашей базы данных оказалось нарушенным,  вы можете повторно
выполнить все изменения зарегистрированные в  протоколе  на  резервной
копии вашей базы данных, и снова привести вашу базу данных в состояние
которое было до момента последней записи в протокол. Типичной командой
чтобы начать протоколирование, будет следующяя:

            SET JOURNAL ON;

  Auditing используется c целью защиты. Она следит за тем, кто и какие
действия выполнял в базе данных,  и сохраняет эту информацию в таблице
доступной  только  очень немногим высоко привилегированным пользовате-
лям.  Конечно,  вы редко будете прибегать к процедуре ревизии,  потому
что  очень скоро она займет много памяти и вам будет сложно работать в
вашей базе данных. Но вы можете устанавливать ревизию для определенных
пользователей, определенных действий или определенных объектов данных.
Имеется такая форма команды AUDIT:

        AUDIT INSERT ON Salespeople BY Diane;

  Или предложение ON или предложение BY могут быть исключены, устанав-
ливая  ревизию,  либо всех объектов или всех пользователей,  соответс-
твенно. Применвние AUDIT ALL, вместо AUDIT INSERT, приведет к отслежи-
ванию всех действий Diane в таблице Продавцов.