Что такое управляющие последовательности (ODBC Escape Sequences)?
Управляющие последовательности (Escape Sequences) входят в стандарт ODBC и предназначены для решения проблем совместимости SQL
для различных серверов баз данных.
В отличие от MS SQL Server, в Firebird и InterBase нет встроенной поддержки управляющих последовательностей,
поэтому мы решили добавить их в IBProvider, чтобы дать возможность пользователям этих серверов писать SQL запросы,
легко переносимые между различными серверами баз данных. Изначально последовательности были реализованы в ODBC драйверах, но впоследствии они перекочевали в OLE DB и были добавлены в Microsoft OLE DB Provider для SQL Server, в IBProvider и во многие другие OLE DB драйвера, которые постепенно вытеснили узкоспециализированную ODBC технологию более универсальной — OLE DB.
ПРИМЕЧАНИЕ
Управляющие последовательности заключаются в фигурные скобки {escape sequence}.
Для включения ODBC парсера в IBProvider в строку подключения необходимо добавить параметр support_odbc_query = true.
Зачем использовать ODBC Escape Sequences?
Некоторые возможности SQL, такие как вызов скалярных функций или хранимых процедур, часто в различных серверах баз данных реализованы различными способами. Для решения проблемы совместимости SQL в рамках стандарта ODBC были разработаны управляющие последовательности (ODBC Escape Sequences).
Для первого примера возьмем операцию сложения строк. В Firebird и Oracle конкатенация строк реализована при помощи операции ||, а в MS SQL Server при помощи операции +. Для того, чтобы ваш запрос был совместим с различными серверами, его необходимо привести к стандартному виду.
Конкатенация в MS SQL:
SELECT (first_name + ‘ ‘ + last_name) as name FROM employee
Конкатенация в Firebird и Oracle:
SELECT (first_name || ‘ ‘ || last_name) FROM employee
Запрос, записанный с применением управляющих последовательностей, будет работать в любых серверах с поддержкой ODBC Escape Sequences:
В качестве еще одного примера подойдет реализация функций работы с датой и временем. Могут различаться дни, которые принимаются в качестве начала недели, реализации подсчета номера недели при переходе через год (функция WEEK), а так же многие другие параметры, которые при отсутствии стандартного подхода могут привести к неправильной работе приложения при смене сервера баз данных.
Не стоит думать, что такие задачи как работа с датой и временем, вызов скалярных функций отличаются только для серверов баз данных различных производителей (Oracle, Firebird, MS SQL). В рамках одного сервера могут так же наблюдаться различия между несколькими версиями. Но использование управляющих последовательностей ODBC должно защитить вас от несоответствий. Собственно для этого и был разработан этот стандарт.
В IBProvider три задачи приведены к стандартному синтаксису ODBC Escape Sequences:
определение даты и времени;
вызов хранимых процедур;
вызов встроенных функций;
Где используются ODBC Escape Sequences?
В MS SQL Server Management Studio для написания унифицированных запросов к связным серверам (Linked Server).
В MS SQL Server Analysis Services при выполнении различных математических расчетов, а так же получении срезов по различным временным интервалам.
В Crystal Reports и Reporting Services (SSRS) для разработки отчетов, не зависящих от сервера баз данных.
В приложениях, которые должны быть независимы от особенностей реализации SQL в различных серверах баз данных.
Последовательности определения даты и времени (Date, Time, Timestamp Escape Sequences).
Название последовательности
Синтаксис
Дата
{d ‘yyyy-mm-dd’}
Время
{t ‘hh:mm:ss’}
Временная метка (Timestamp)
{ts ‘yyyy-mm-dd hh:mm:ss’}
Пример обработки строки с датой через управляющую последовательность:
SELECT COUNT(id) AS cnt
FROM employee
WHERE hire_date > {d ‘2007-01-01’}
ПРИМЕЧАНИЕ
В примере строка с датой записана в стандартном формате управляющей последовательности {d ‘yyyy-mm-dd’}, а далее она уже приводится к тому формату, в котором хранятся даты на конкретном сервере баз данных.
Последовательность для вызова хранимой процедуры (Procedure Call Escape Sequence).
Хранимые процедуры так же могут быть вызваны различными способами:
select * from sp_name
exec sp_name(params)
execute sp_name(params)
Возвращает длину в символах строкового выражения. Эквивалентна функции CHARACTER_LENGTH.
{fn CHAR_LENGTH(‘hello’)} = 5
CHARACTER_LENGTH(string_exp)
Возвращает длину в символах строкового выражения. Эквивалентна функции CHAR_LENGTH.
{fn CHARACTER_LENGTH (‘hello’)} = 5
CONCAT (string_exp1, string_exp2)
Возвращает результат объединения двух строковых выражений.
{fn CONCAT(‘Hel’, ‘lo’)} = ‘Hello’
INSERT (string_exp1, start, length, string_exp2)
Возвращает строковое выражение, где в строке string_exp1, начиная с символа start, length символов заменены строкой string_exp2.
{fn INSERT(‘1.23.2′,3,2,’8’)} = ‘1.8.2’
LCASE (string_exp)
Возвращает строковое выражение, приведенное к нижнему регистру.
{fn LCASE(‘HELLO’)} = ‘ hello’
LEFT (string_exp, count)
Возвращает левую часть строкового выражения.
{fn LEFT(‘ hello’, 4)} = ‘ hell’
LENGTH (string_exp)
Возвращает длину строки в символах без оконечных пробелов.
{fn LENGTH(‘ hello ‘)} = 5
LOCATE (string_exp1, string_exp2[, start])
Возвращает позицию первого вхождения string_exp1 в string_exp2. Если аргумент start не указан, то поиск идет с первого символа. Если строка не найдена, то функция возвращает 0.
Возвращает позицию первого вхождения string_exp1 в string_exp2. Если строка не найдена, то функция возвращает 0.
{fn POSITION(‘ll’ IN ‘hello’)} = 3 {fn POSITION(‘la’ IN ‘hello’)} = 0
RIGHT (string_exp, count)
Возвращает count символов с конца строки.
{fn RIGHT(‘hello’, 2)} = ‘lo’
RTRIM (string_exp)
Удаляет пробелы с конца строки.
{fn RTRIM (‘ hello ‘)} = ‘ hello’
SPACE (count)
Возвращает строку, состоящую из count пробелов.
{fn SPACE(5)} = ‘ ‘
SUBSTRING (string_exp, start, length)
Возвращает часть строки string_exp, начиная с позиции start длиной length.
{fn SUBSTRING(‘hello’, 2, 3)} = ‘ell’
UCASE (string_exp)
Возвращает строку, приведенную к верхнему регистру.
{fn UCASE (‘Hello’)} = ‘HELLO’
Числовые функции
Функция
Описание
Примеры
ABS (numeric_exp)
Возвращает абсолютную величину аргумента.
{fn ABS(-5)} = 5 {fn ABS(5)} = 5
ACOS (float_exp)
Возвращает арккосинус угла, указанного в радианах.
{fn ACOS(1)} = 0
ASIN (float_exp)
Возвращает арккосинус угла, указанного в радианах.
{fn ASIN(0)} = 1
ATAN (float_exp)
Возвращает арктангенс угла, указанного в радианах.
{fn ATAN(0)} = 0
ATAN2 (float_exp1, float_exp2)
Возвращает арктангенс угла, отсчитываемого от оси 0X до точки (float_exp1, float_exp2)
{fn ATAN2(0, 1)} = 0
CEILING (numeric_exp)
Возвращает наименьшее целое, большее или равное аргументу.
{fn CEILING(5.6)} = 6 {fn CEILING(-5.6)} = -5
COS (float_exp)
Возвращает косинус угла, указанного в радианах.
{fn COS(0)} = 1
COT (float_exp)
Возвращает котангенс угла, указанного в радианах.
{fn COT(1)} = 0.642(…)
DEGREES (numeric_exp)
Преобразует радианы в градусы.
{fn DEGREES(1)} = 57.295(…)
EXP (float_exp)
Возвращает экспоненту числа.
{fn EXP(0)} = 1
FLOOR (numeric_exp)
Возвращает наименьшее целое, меньшее или равное аргументу.
{fn FLOOR(5.6)} = 5 {fn FLOOR(-5.6)} = -6
LOG (float_exp)
Возвращает натуральный логарифм числа.
{fn LOG(1)} = 0
LOG10 (float_exp)
Возвращает десятичный логарифм числа.
{fn LOG10(1)} = 0
MOD (integer_exp1, integer_exp2)
Возвращает результат деления по модулю integer_exp1 на integer_exp2.
{fn MOD (16, 6)} = 4
PI ( )
Возвращает число PI.
{fn PI()} = 3.1419…
POWER (numeric_exp, integer_exp)
Возвращает результат возведения числа numeric_exp в степень integer_exp.
{fn POWER(2,3)} = 8
RADIANS (numeric_exp)
Преобразует градусы в радианы.
{fn RADIANS(360)} = 6.283…
RAND ()
Возвращает случайное число.
{fn RAND()} = (случайное число в диапазоне [0..1])
ROUND (numeric_exp, integer_exp)
Возвращает результат округления числа numeric_exp до integer_exp знаков после запятой. Если integer_exp отрицательное, то округление идет до |integer_exp| знаков перед запятой.
Возвращает знак числа. Если numeric_exp больше нуля, то возвращается 1. Если numeric_exp меньше нуля, то возвращается -1. Если numeric_exp равно нулю возвращается 0.
Возвращает результат отсечения от числа numeric_exp разрядов вплоть до integer_exp знаков после запятой. Если integer_exp отрицательное, то отсечение идет до |integer_exp| знаков перед запятой.
first_week_day — параметр устанавливается в строке подключения или в параметрах команды (в ADO). По умолчанию он равен 1 (Понедельник).
Для версий InterBase >= 7.5, Firebird >= 1.5 и Yaffil возвращаются названия дней недели Monday, Tuesday, Wednesday, и т.д. Для более старых версий: WEEKDAY_1 — для понедельника WEEKDAY_2 — вторник WEEKDAY_3 — среда и т.д.
Для версий InterBase >= 7.5, Firebird >= 1.5, Yaffil: {fn DAYNAME({d ‘2007-10-01’})} = ‘Monday’
Для более старых версий: first_week_day = 1 [default] {fn DAYNAME({d ‘2007-04-01’})} = ‘WEEKDAY_1’
Возвращает номер дня месяца как целое значение в диапазоне от 1 до 31.
{fn DAYOFMONTH({d ‘2007-01-25’})} = 25
DAYOFWEEK (date_exp)
Возвращает номер дня недели, как целое значение в диапазоне от 1 до 7. Возвращаемое значение зависит от свойства инициализации first_week_day.Описание параметра first_week_day см. в DAYNAME
Если first_week_day = 1 [default] {fn DAYOFWEEK({d ‘2007-01-07’})} = 7
Если first_week_day = 7 {fn DAYOFWEEK({d ‘2007-01-07’})} = 1
DAYOFYEAR (date_exp)
Возвращает номер дня года как целое значение в диапазоне от 1 до 366.
Возвращает временную метку, полученную путем добавления к timestamp_exp значения integer_exp для интервала interval. interval может принимать следующие значения:
Возвращает разницу в interval, на которую timestamp_exp2 больше чем timestamp_exp1, выраженную целым числом. interval может принимать следующие значения:
Если exp является null, тогда функция возвращает value. Если exp не является null, тогда функция возвращает exp. Тип данных value должен быть совместим с типом данных exp.
Возвращает значение value_exp, приведенное к типу data_type.
data_type может принимать следующие значения:
SQL_BIT,
SQL_BIGINT,
SQL_CHAR,
SQL_DECIMAL,
SQL_DOUBLE,
SQL_FLOAT,
SQL_INTEGER,
SQL_LONGVARCHAR,
SQL_NUMERIC,
SQL_REAL,
SQL_SMALLINT,
SQL_DATE,
SQL_TIME,
SQL_TIMESTAMP,
SQL_VARCHAR.
Для некоторых типов опционально могут быть указаны дополнительные параметры: SQL_CHAR(size), SQL_DECIMAL(scale, precision), SQL_NUMERIC(scale, precision), SQL_VARCHAR(size).