alan_beaulieu-learning_sql-ru (865932), страница 24
Текст из файла (страница 24)
В следующем примере строка в столбце text_fld изменяется путем добавления в ее конец дополнительной фразы:mysql> UPDATE string_tbl> SET text_fld = CONCAT(text_fld, ', but now it is longer');Query OK, 1 row affected (0.03 sec)Rows matched: 1 Changed: 1 Warnings: 0Теперь столбец text_fld содержит следующую строку:mysql> SELECT text_fld> FROM string_tbl;++| text_fld|++| This string was 29 characters, but now it is longer |++1 row in set (0.00 sec)Таким образом, как и все функции, возвращающие строку, concat()можно использовать для замещения данных, хранящихся в столбцесимвольного типа.Другое традиционное применение функции concat() – построение строки из отдельных частей данных.
Например, следующий запрос формирует строку примечания для каждого операциониста банка:mysql> SELECT CONCAT(fname, ' ', lname, ' has been a ',> title, ' since ', start_date) emp_narrative> FROM employee> WHERE title = 'Teller' OR title = 'Head Teller';++| emp_narrative|++| Helen Fleming has been a Head Teller since 20040317 || Chris Tucker has been a Teller since 20040915|| Sarah Parker has been a Teller since 20021202|| Jane Grossman has been a Teller since 20020503|| Paula Roberts has been a Head Teller since 20020727 || Thomas Ziegler has been a Teller since 20001023|| Samantha Jameson has been a Teller since 20030108|| John Blake has been a Head Teller since 20000511|| Cindy Mason has been a Teller since 20020809|Строковые данные133| Frank Portman has been a Teller since 20030401|| Theresa Markham has been a Head Teller since 20010315 || Beth Fowler has been a Teller since 20020629|| Rick Tulman has been a Teller since 20021212|++13 rows in set (0.12 sec)Функция concat() может обрабатывать любое выражение, возвращающее строку, и даже преобразует числа и даты в строковый формат,о чем свидетельствует столбец дат (start_date), используемый как аргумент.
Хотя Oracle Database включает функцию concat(), она можетпринимать только строковые аргументы, поэтому в Oracle предыдущий запрос работать не будет. В этом случае придется использоватьоператор конкатенации (||), а не вызов функции:SELECT fname || ' ' || lname || ' has been a ' ||title || ' since ' || start_date emp_narrativeFROM employeeWHERE title = 'Teller' OR title = 'Head Teller';В SQL Server нет функции concat(), поэтому используется такой жеподход, что и в предыдущем примере, только с применением оператора конкатенации SQL Server (+, а не ||).Функция concat() полезна для добавления символов в начало или конецстроки, но также позволяет ввести или заменить символы в серединестроки.
Все три сервера БД предоставляют специальные функции дляэтого, но все они разные, поэтому сначала рассмотрим функциюMySQL, а затем перейдем к функциям двух других серверов.MySQL включает функцию insert(), которая принимает четыре аргумента: исходную строку, начальное положение, число символов, требующих замены, и замещающую строку. В зависимости от значениятретьего аргумента функция выполняет вставку либо замену символовстроки. Если третий аргумент равен нулю, то замещающая строкавставляется со сдвигом всех последующих символов вправо, например:mysql> SELECT INSERT('goodbye world', 9, 0, 'cruel ') string;++| string|++| goodbye cruel world |++1 row in set (0.00 sec)В этом примере все символы, начиная с девятого, сдвигаются вправо,и вставляется строка 'cruel '. Если третий аргумент больше нуля, тозамещающая строка замещает указанное количество символов, например:mysql> SELECT INSERT('goodbye world', 1, 7, 'hello') string;++134Глава 7.
Создание, преобразование и работа с данными| string|++| hello world |++1 row in set (0.00 sec)В этом примере первые семь символов замещаются строкой 'hello'.В Oracle Database нет единой функции, обладающей гибкостью insert() MySQL, но в Oracle есть функция replace(), замещающая однуподстроку другой. Вот предыдущий пример, переработанный с использованием replace():SELECT REPLACE('goodbye world', 'goodbye', 'hello')FROM dual;Все экземпляры строки 'goodbye' будут замещены строкой 'hello'.В результате получаем строку 'hello world'. Функция заместит все экземпляры искомой строки замещающей строкой – будьте внимательны, чтобы не получить больше замещений, чем задумано.В SQL Server есть и функция replace() с той же функциональностью, чтои в Oracle, а также функция stuff() (заполнить), функциональные возможности которой аналогичны функции insert() MySQL.
Вот пример:SELECT STUFF('hello world', 1, 5, 'goodbye cruel')Во время выполнения этого запроса удаляются пять символов, начиная с первой позиции, и на их место вставляется строка 'goodbye cruel'. В результате получаем строку 'goodbye cruel world'.Кроме вставки символов в строку может понадобиться извлечь из строки подстроку. Для этого все три сервера включают функцию substring() (подстрока) (правда, в Oracle Database эта функция называется substr()). Она извлекает указанное число символов, начиная с заданной позиции.
В следующем примере из строки извлекается пятьсимволов, начиная с девятой позиции:mysql> SELECT SUBSTRING('goodbye cruel world', 9, 5);++| SUBSTRING('goodbye cruel world', 9, 5) |++| cruel|++1 row in set (0.00 sec)Кроме упомянутых, все три сервера включают множество другихвстроенных функций для работы со строковыми данными. Хотя назначение многих из них сугубо специальное, например формированиестрокового эквивалента восьмеричных или шестнадцатеричных чисел, есть и функции общего назначения, например удаляющие или добавляющие пробелы в конце текстовой строки.
Более подробную информацию можно получить в справочном руководстве по SQL для кон135Числовые данныекретного сервера или универсальном справочнике по SQL, например«SQL in a Nutshell» (O’Reilly).Числовые данныеВ отличие от строковых данных (и временных, как вы вскоре увидите)числовые данные довольно просты. Число можно ввести с клавиатуры, извлечь из другого столбца или сформировать с помощью вычисления.
Для вычислений доступны все обычные арифметические операторы (+, , *, /), а для задания порядка вычислений – скобки:mysql> SELECT (37 * 59) / (78 (8 * 6));++| (37 * 59) / (78 (8 * 6)) |++|72.77 |++1 row in set (0.00 sec)Как упоминалось в главе 2, основная проблема при хранении числовых данных – возможное округление (иногда очень грубое) при превышении предела, заданного для числового столбца. Например, число999,99 при сохранении в столбце, определенном как float(3,1), будетокруглено до 99,9.Выполнение арифметических операцийБольшинство встроенных числовых функций предназначено для выполнения определенных арифметических операций, таких как вычисление квадратного корня числа.
В табл. 7.1 перечислены некоторыераспространенные числовые функции, принимающие один числовойаргумент и возвращающие число.Таблица 7.1. Одноаргументные числовые функцииФункцияОписаниеAcos(x)Вычисляет арккосинус xAsin(x)Вычисляет арксинус xAtan(x)Вычисляет арктангенс xCos(x)Вычисляет косинус xCot(x)Вычисляет котангенс xExp(x)Вычисляет exLn(x)Вычисляет натуральный логарифм xSin(x)Вычисляет синус xSqrt(x)Вычисляет квадратный корень из xTan(x)Вычисляет тангенс x136Глава 7. Создание, преобразование и работа с даннымиЭти функции осуществляют очень специальные задачи.
Не будем приводить здесь примеры для них (если читатель не узнаёт функцию по названию или описанию, то, скорее всего, она ему не нужна). Однако другие числовые функции, используемые в вычислениях, чуть более гибкии заслуживают некоторого пояснения.Например, оператор modulo, вычисляющий остаток от деления одногочисла на другое, реализован в MySQL и Oracle Database функцией mod().В следующем примере вычисляется остаток от деления 10 на 4:mysql> SELECT MOD(10,4);++| MOD(10,4) |++|2 |++1 row in set (0.02 sec)Обычно функция mod() используется с целыми аргументами, но в MySQL 4.1.7 и более поздних версий допустимы и вещественные аргументы:mysql> SELECT MOD(22.75, 5);++| MOD(22.75, 5) |++|2.75 |++1 row in set (0.02 sec)В SQL Server нет функции mod().
Вместо нее для нахождения остатка используется оператор %. Следовательно, выражение 10 % 4дает в результате значение 2.Другая числовая функция, принимающая два числовых аргумента, –функция pow() (в Oracle Database или SQL Server – power()), котораявозвращает первое число в степени, равной второму числу, например:mysql> SELECT POW(2,8);++| POW(2,8) |++|256 |++1 row in set (0.03 sec)Таким образом, pow(2,8) – эквивалент MySQL для записи 28. Поскольку память компьютера распределена блоками по 2x байт, с помощьюфункции pow() может быть удобно определять точное число байт в памяти определенного объема:mysql> SELECT POW(2,10) kilobyte, POW(2,20) megabyte,> POW(2,30) gigabyte, POW(2,40) terabyte;Числовые данные137+++++| kilobyte | megabyte | gigabyte | terabyte|+++++|1024 | 1048576 | 1073741824 | 1099511627776 |+++++1 row in set (0.00 sec)Не знаю как вам, но мне проще запомнить гигабайт как 230 байт, а некак число 1 073 741 824.Управление точностью числовых данныхЧисла с плавающей точкой не всегда обязаны взаимодействовать илиотображаться полностью.
Например, можно хранить данные о денежных операциях с точностью до шести десятичных разрядов, но приотображении округлять их до сотых. Для ограничения точности чиселс плавающей точкой предназначены четыре функции – ceil(), floor(),round() и truncate(). Все три сервера включают эти функции, толькоOracle Database использует trunc() вместо truncate(), а SQL Server –ceiling() вместо ceil().Функции ceil() (потолок) и floor() (пол) предназначены для округления вверх или вниз до ближайшего целого, как показано в следующемпримере:mysql> SELECT CEIL(72.445), FLOOR(72.445);+++| CEIL(72.445) | FLOOR(72.445) |+++|73 |72 |+++1 row in set (0.06 sec)Как видите, любое число в диапазоне между 72 и 73 округляется до 73(функция ceil()) или до 72 (функция floor()).
Необходимо помнить,что ceil() округлит до 73, даже если десятичная часть числа очень мала, и floor() округлит до 72, даже если десятичная часть достаточновелика:mysql> SELECT CEIL(72.000000001), FLOOR(72.999999999);+++| CEIL(72.000000001) | FLOOR(72.999999999) |+++|73 |72 |+++1 row in set (0.00 sec)Если предыдущие функции предлагают округления, слишком грубыедля приложения, можно использовать функцию round() (округлить).Она округляет в большую или меньшую сторону от середины промежутка между двумя целыми, например:138Глава 7.