ПРИЛОЖЕНИЕ C

        ----------------------------------------------------------------

        СЕМАНТИКА ПРИСВАИВАНИЯ И СРАВНЕНИЯ СТРОК


        В  этом  приложении  объясняются  семантические  различия  между
        базовыми  типами  данных  CHAR  и  VARCHAR2.  В ORACLE7 и PL/SQL
        версии  2  семантика  типа  CHAR  была  слегка  изменена,  чтобы
        привести ее  в соответствие  с текущим  стандартом ANSI/ISO SQL.
        Эти изменения играют роль,  когда вы сравниваете и  присваиваете
        символьные значения  (в частности,  в операциях  INSERT, UPDATE,
        SELECT или FETCH).

















































                           Семантика присваивания и сравнения строк  C-1


----------------

Присваивание символьных значений

        Когда вы присваиваете символьное значение переменной CHAR,  если
        это значение  короче, чем  объявленная длина  переменной, PL/SQL
        дополняет   его   пробелами   до   объявленной   длины.  Поэтому
        информация  о  существующих  хвостовых  пробелах,  если  таковые
        имеются   в   присваиваемом   значении,   теряется.    Например,
        рассмотрим следующие объявления:

        name1  CHAR(10);
        name2  CHAR(10);

        После присваиваний

        name1 := 'Tom & ';  -- заметьте хвостовой пробел
        name2 := 'Jerry';

        значения как name1,  так и name2  будут иметь по  пять хвостовых
        пробелов.

        Если  символьное   значение  длиннее,   чем  объявленная   длина
        переменной  CHAR,  то  PL/SQL  снимает  операцию  присваивания и
        возбуждает предопределенное  исключение VALUE_ERROR.   PL/SQL не
        усекает такое  значение и  даже не  пытается отстричь  хвостовые
        пробелы.  Например, при объявлении переменной

        acronym  CHAR(4);

        следующее присваивание возбудит исключение VALUE_ERROR:

        acronym := 'SPCA ';  -- заметьте хвостовой пробел

        Когда вы присваиваете  символьное значение переменной  VARCHAR2,
        если это значение короче объявленной длины переменной, PL/SQL не
        дополняет  его  пробелами  и  не  отстригает хвостовых пробелов.
        Значение присваивается как оно есть, так что никакая  информация
        не теряется.  Если символьное значение длиннее, чем  объявленная
        длина  переменной,  то  PL/SQL  снимает  операцию присваивания и
        возбуждает предопределенное  исключение VALUE_ERROR.   PL/SQL не
        усекает такое значение и не пытается отстричь хвостовые пробелы.





















C-2  Руководство пользователя и справочник по PL/SQL


----------------

Сравнение символьных значений

        Вы  можете  использовать   операторы  отношений  для   сравнения
        символьных  значений  на  равенство  или неравенство.  Сравнения
        базируются  на  сопоставляющей  последовательности, используемой
        набором символов базы  данных.  Одно символьное  значение больше
        другого,  если  первое   следует  за  вторым   в  сопоставляющей
        последовательности.  Например, следующее условие IF дает TRUE:

        name1 := 'COLES';
        name2 := 'COLEMAN';
        IF (name1 > name2) THEN ...

        ANSI/ISO SQL требует, чтобы два сравниваемых символьных значения
        имели одинаковую длину.  Поэтому, если оба значения в  сравнении
        принадлежат типу CHAR, используется ДОПОЛНЯЮЩАЯ СЕМАНТИКА.   Это
        значит, что перед сравнением символьных строк неодинаковой длины
        PL/SQL дополняет короткое значение пробелами до длины  длинного.
        Например, при объявлениях

        name1  CHAR(4) := 'BELL';
        name2  CHAR(6) := 'BELL  ';  -- заметьте хвостовые пробелы

        следующее условие IF дает TRUE:

        IF (name1 = name2) THEN ...

        Если  хотя  бы  одно  из  сравниваемых значений принадлежит типу
        VARCHAR2, то используется НЕДОПОЛНЯЮЩАЯ СЕМАНТИКА.  Это  значит,
        что перед сравнением символьных строк неодинаковой длины  PL/SQL
        не дополняет  значений пробелами  и использует  их точные длины.
        Например, при объявлениях

        name1  VARCHAR2(10) := 'DOW';
        name2  CHAR(10)     := 'DOW  ';  -- заметьте хвостовые пробелы

        следующее условие IF дает FALSE:

        IF (name1 = name2) THEN ...

        Как  указывалось  в  главе  2,  все строковые литералы имеют тип
        CHAR.   Следовательно,  если  оба  значения в сравнении являются
        литералами, используется дополняющая семантика.  Если  литералом
        является  лишь  одно  из  значений,  то  дополняющая   семантика
        используется  только  в   том  случае,  когда   второе  значение
        принадлежит типу CHAR.















                           Семантика присваивания и сравнения строк  C-3


----------------

Вставка символьных значений

        Когда   вы   выполняете   операцию   INSERT,   вставляя значение
        символьной переменной PL/SQL в столбец базы данных ORACLE, будет
        ли это значение дополняться пробелами или нет - зависит от  типа
        столбца, но НЕ от типа переменной.

        При  вставке  символьного  значения  в  столбец базы данных CHAR
        ORACLE не отстригает  хвостовых пробелов.  Если  значение короче
        объявленной  ширины  столбца,   ORACLE  дополняет  значение   до
        объявленной  ширины.   Как  следствие,  информация  о  хвостовых
        пробелах исходного значения теряется.  Если символьное  значение
        длиннее  объявленной  ширины  столбца  CHAR,  ORACLE  генерирует
        ошибку и отменяет операцию.  ORACLE не усекает такое значение  и
        не отстригает хвостовых пробелов.

        При вставке символьного значения в столбец базы данных  VARCHAR2
        ORACLE также  не отстригает  хвостовых пробелов.   Если значение
        короче объявленной ширины столбца, ORACLE не дополняет  значение
        до объявленной ширины.  Символьное значение записывается как оно
        есть,  и  информация  о  хвостовых  пробелах  исходного значения
        сохраняется.   Если  символьное  значение  длиннее   объявленной
        ширины столбца VARCHAR2, то ORACLE генерирует ошибку и  отменяет
        операцию.   ORACLE  не  усекает  такое  значение и не отстригает
        хвостовых пробелов.

        Те же правила действуют при операции UPDATE.


----------------

Выборка символьных значений

        Когда вы  выполняете операцию  SELECT, выбирая  значение столбца
        базы данных ORACLE в символьную переменную PL/SQL, будет ли  это
        значение  дополняться  пробелами  или  нет  -  зависит  от  типа
        переменной, но НЕ от типа столбца.

        При  выборке  значения  столбца  в  переменную  CHAR,  если  это
        значение короче объявленной  длины переменной, ORACLE  дополняет
        значение  до  объявленной  длины.   Как  следствие, информация о
        хвостовых пробелах исходного значения теряется.  Если символьное
        значение  столбца  длиннее  объявленной  длины  переменной CHAR,
        ORACLE  усекает  значение,   выполняет  присваивание,  а   затем
        заставляет   PL/SQL   возбудить   предопределенное    исключение
        VALUE_ERROR.

        При выборке  значения столбца  в переменную  VARCHAR2, если  это
        значение  короче   объявленной  длины   переменной,  ORACLE   не
        дополняет  это  значение  до  объявленной  длины и не отстригает
        хвостовых пробелов.  Символьное  значение присваивается как  оно
        есть, так что информация о хвостовых пробелах исходного значения
        не   теряется.    Если   символьное   значение   столбца длиннее
        объявленной  длины  переменной   VARCHAR2,  то  ORACLE   усекает
        значение,  выполняет  присваивание,  а  затем  заставляет PL/SQL
        возбудить предопределенное исключение VALUE_ERROR.


        Те же правила действуют при операции FETCH.


C-4  Руководство пользователя и справочник по PL/SQL


----------------

Рекомендации

        В данном исполнительном окружении, эквивалентность типов  данных
        CHAR  и  VARCHAR2  определяется  командой  или  опцией,  которая
        устанавливает режим совместимости с версией 6 или режим ORACLE7.
        Например, в среде SQL*Plus вы выдаете команду SET COMPATIBILITY,
        специфицируя значение V6 или V7 (умолчание), например:

        SQL> SET COMPATIBILITY V6

        Другим  примером  может  служить  среда прекомпилятора ORACLE, в
        которой вы указываете опцию  режима выполнения DBMS в  командной
        строке, например:

        ... DBMS=V6 ...

        Умалчиваемым режимом является DBMS=NATIVE, что специфицирует  ту
        версию ORACLE,  которая установлена  в вашей  системе (это может
        быть версия 6 или более поздняя).

        При  вставке  в  базу  данных  символьных  значений  вы   можете
        гарантировать,  что  хвостовые  пробелы  не будут сохраняться, с
        помощью  функции  RTRIM,  которая  отсекает  хвостовые  пробелы,
        например:

        my_empno := 7471;
        my_ename := 'LEE    ';  -- заметьте хвостовые пробелы
        ...
        INSERT INTO emp
            VALUES (my_empno, RTRIM(my_ename), ...);  -- вставит 'LEE'