alan_beaulieu-learning_sql-ru (865932), страница 22
Текст из файла (страница 22)
Однакоэта глава посвящена созданию, преобразованию и работе со строковыми, числовыми и временными данными, а язык SQL не включает команды, обеспечивающие эти функциональные возможности. Вернее,все эти операции осуществляются встроенными функциями. К томуже, хотя стандарт SQL и описывает некоторые функции, производители БД часто отступают от их спецификаций.Поэтому в данной главе сначала показаны некоторые общие приемы работы с данными в SQLвыражениях, а потом продемонстрированы отдельные встроенные функции, реализованные в Microsoft SQL Server,Oracle Database и MySQL.
Кроме материала, представленного в этойглаве, настоятельно рекомендуется приобрести справочное руководство с описанием всех функций, реализованных сервером, с которым выработаете. Если вы работаете с несколькими серверами, есть ряд справочников, охватывающих несколько серверов, например «SQL in a Nutshell» или «SQL Pocket Guide», оба от издательства O’Reilly.Строковые данныеПри работе со строковыми данными используется один из следующихсимвольных типов данных:CHARПредназначен для хранения строк фиксированной длины, дополненных пробелами. MySQL допускает значения типа CHAR длинойдо 255 символов, Oracle Database – до 2000 символов, а SQL Server –до 8000 символов.Строковые данные123varcharПредназначен для хранения строк переменной длины.
MySQL допускает в столбце типа varchar до 255 символов (65 535 символовдля версии 5.0 и выше), Oracle Database (с помощью типа varchar2) –до 4000 символов, а SQL Server – до 8000 символов.text (MySQL и SQL Server) или CLOB (Character Large Object; Oracle Database)Позволяют хранить очень большие строки переменной длины (обычно в этом контексте их называют документами). В MySQL есть несколько текстовых типов (tinytext, text, mediumtext и longtext) длядокументов размером до 4 Гбайт. В SQL Server всего один тип textдля документов размером до 2 Гбайт.
Oracle Database включаеттип данных CLOB, позволяющий хранить колоссальные документыдо 128 Тбайт.В некоторых примерах данного раздела, иллюстрирующих применение этих различных типов, я использую такую таблицу:CREATE TABLE string_tbl(char_fld CHAR(30),vchar_fld VARCHAR(30),text_fld TEXT);В следующих двух разделах показано, как создавать строковые данные и работать с ними.Создание строкСамый простой способ заполнить символьный столбец – заключитьстроку в кавычки:mysql> INSERT INTO string_tbl (char_fld, vchar_fld, text_fld)> VALUES ('This is char data',> 'This is varchar data',> 'This is text data');Query OK, 1 row affected (0.00 sec)При вставке строковых данных в таблицу не забывайте, что если длинастроки превышает максимальный размер символьного столбца (или заданный, или допустимый максимум типа данных), сервер или сформирует исключение (Oracle Database), или, в случае MySQL или SQL Server, без лишнего шума усечет строку (MySQL генерирует предупреждение).
Чтобы показать, как MySQL поведет себя в такой ситуации, следующее выражение update пытается обновить строкой из 46 символовстолбец vchar_fld, для которого задан максимальный размер в 30 символов:mysql> UPDATE string_tbl> SET vchar_fld = 'This is a piece of extremely long varchar data';124Глава 7. Создание, преобразование и работа с даннымиQuery OK, 1 row affected, 1 warning (0.01 sec)Rows matched: 1 Changed: 1 Warnings: 1Столбец изменен, но сформировано следующее предупреждение:mysql> SHOW WARNINGS;++++| Level | Code | Message|++++| Warning | 1265 | Data truncated for column 'vchar_fld' at row 1 |++++1 row in set (0.00 sec)Если извлечь столбец vchar_fld, то получим:mysql> SELECT vchar_fld> FROM string_tbl;++| vchar_fld|++| This is a piece of extremely l |++1 row in set (0.05 sec)Как видите, в столбце vchar_fld размещены только первые 30 символов46символьной строки.
Лучший способ избежать усечения строки (илиформирования исключений в случае Oracle Database) при работесо столбцами типа varchar – задавать достаточно большой верхний предел длины строки, чтобы иметь возможность работать с самыми длинными из предполагаемых для хранения строк (помня о том, что серверраспределяет для хранения строки лишь необходимое количество памяти, т. е.
при задании большого верхнего предела для столбцов типаvarchar память все же не расходуется впустую).Одинарные кавычки (апострофы)Поскольку строки разграничиваются одинарными кавычками, необходимо быть внимательными со строками, включающими одинарныекавычки (апострофы). Например, следующую строку вставить не получится, потому что сервер подумает, что апостроф в слове «doesn’t»обозначает конец строки:UPDATE string_tblSET text_fld = 'This string doesn't work';Чтобы заставить сервер «проигнорировать» апостроф в слове «doesn’t»,понадобится добавить в строку знак экранирования символа (escape).Тогда сервер будет воспринимать апостроф как обычный символ строки. Все три сервера обеспечивают возможность сохранить апостроф;для этого надо ввести непосредственно перед апострофом еще одинапостроф:mysql> UPDATE string_tbl> SET text_fld = 'This string didn''t work, but it does now';125Строковые данныеQuery OK, 1 row affected (0.01 sec)Rows matched: 1 Changed: 1 Warnings: 0Пользователи Oracle Database и MySQL также могут сохранитьодинарную кавычку, разместив прямо перед ней обратный слэш:UPDATE string_tbl SET text_fld ='This string didn\'t work, but it does now'При извлечении строки для отображения на экране или в поле сообщения ее внутренние кавычки не требуют какойлибо особой обработки:mysql> SELECT text_fld> FROM string_tbl;++| text_fld|++| This string didn't work, but it does now |++1 row in set (0.00 sec)Однако если строка извлекается для помещения в файл, предназначенный для другой программы, возможно, вы захотите вставить в извлеченную строку знак экранирования символа.
При работе с MySQL можно использовать встроенную функцию quote() (кавычка), которая заключает в кавычки всю строку и добавляет знаки экранирования символа к любой одинарной кавычке/апострофу, встречающейся в строке.Вот как выглядит строка, извлеченная с применением функции quote():mysql> SELECT QUOTE(text_fld)> FROM string_tbl;++| QUOTE(text_fld)|++| 'This string didn\'t work, but it does now' |++1 row in set (0.04 sec)При извлечении данных с целью экспорта вы, возможно, захотитеприменить функцию quote() ко всем символьным столбцам, сформированным не системой, таким как столбец customer_notes (примечанияклиента).Специальные символыЕсли приложение предполагается применять в разных странах, строки могут включать символы, которых нет на клавиатуре разработчика.
Например, при работе с французским и немецким языками можетпонадобиться включать символы с диакритическими знаками, такие..как eЂили o. Серверы SQL Server и MySQL включают встроенную функцию char(), позволяющую создавать строки из всех 255 символов набора ASCII (пользователи Oracle Database могут применять функцию126Глава 7. Создание, преобразование и работа с даннымиchr()). Для примера следующий фрагмент кода извлекает напечатанную строку и ее эквивалент, собранный из отдельных символов:mysql> SELECT 'abcdefg', CHAR(97,98,99,100,101,102,103);+++| abcdefg | CHAR(97,98,99,100,101,102,103) |+++| abcdefg | abcdefg|+++1 row in set (0.01 sec)Таким образом, 97й символ набора символов ASCII – это буква a. Приведенные выше символы не являются специальными, а вот следующий пример показывает местоположение символов с диакритическими знаками и других специальных символов, таких как знаки валют:mysql> SELECT CHAR(128,129,130,131,132,133,134,135,136,137);++| CHAR(128,129,130,131,132,133,134,135,136,137) |++||++1 row in set (0.01 sec)mysql> SELECT CHAR(138,139,140,141,142,143,144,145,146,147);++| CHAR(138,139,140,141,142,143,144,145,146,147) |++||++1 row in set (0.01 sec)mysql> SELECT CHAR(148,149,150,151,152,153,154,155,156,157);++| CHAR(148,149,150,151,152,153,154,155,156,157) |++||++1 row in set (0.00 sec)mysql> SELECT CHAR(158,159,160,161,162,163,164,165);++| CHAR(158,159,160,161,162,163,164,165) |++||++1 row in set (0.01 sec)В примерах данного раздела используется набор символовlatin1.
Если сеанс cконфигурирован под другой набор, вы увидите символы, отличные от приведенных здесь. Идея та же, но,чтобы находить определенные символы, вам придется освоитьрасположение символов своего набора.127Строковые данныеПостроение строк символ за символом может быть достаточно утомительным, особенно если в строке всего лишь несколько символов с диакритическими знаками. К счастью, можно воспользоваться функциейconcat() и соединить отдельные строки, часть которых можно ввестис клавиатуры, а другие – сформировать с помощью функции char().Например, следующий фрагмент кода показывает, как построить фра..зу danke schon с помощью функций concat() и char():mysql> SELECT CONCAT('danke sch', CHAR(148), 'n');++| CONCAT('danke sch', CHAR(148), 'n') |++..| danke schon|++1 row in set (0.00 sec)Пользователи Oracle Database вместо функции concat() могутприменять оператор конкатенации (||):SELECT 'danke sch' || CHR(148) || 'n'FROM dual;В SQL Server нет функции concat(), поэтому придется использовать оператор конкатенации (+):SELECT 'danke sch' + CHAR(148) + 'n'Найти ASCIIэквивалент нужного символа можно с помощью функции ascii(), принимающей самый левый символ строки и возвращающей его номер:..mysql> SELECT ASCII('o ');++..| ASCII('o') |++|148 |++1 row in set (0.00 sec)Функции char(), ascii() и concat() (как и операторы конкатенации) позволяют работать с любым романским языком, даже если клавиатуране включает символы с диакритическими знаками или спецсимволы.Работа со строкамиКаждый сервер БД включает множество встроенных функций для работы со строками.