Orafce
Это расширение QHB реализует функции и операторы, которые эмулируют подмножество функций и пакетов из Oracle RDBMS.
Обратите внимание, что эта версия orafce работает с QHB версии 1.5.1 и выше.
Установка
Функции совместимости и пакеты Oracle для QHB поставляется в виде пакета qhb-1.5.2-orafce.
Подключите репозиторий пакетов QHB и установите пакет расширения для выбранной платформы со страницы загрузки.
Функции и пакеты Oracle
Этот модуль содержит несколько полезных функций, которые могут помочь при переносе приложения Oracle на QHB или могут быть полезными в целом.
Встроенные функции даты Oracle были протестированы на совместимость с Oracle 10. Диапазоны дат с 1960 по 2070 год работают корректно. Даты до 1582-10-05 с форматом 'J' и до 1100-03-01 с остальными форматами нельзя проверить из-за дефекта в Oracle.
Все функции полностью совместимы с Oracle и учитывают все известные строки формата.
Список строк формата для функций trunc, round
Y,YY,YYY,YYYY,SYYY,SYEAR год
I,IY,IYY,IYYY недельный год по ISO 8601
Q квартал
WW неделя, начиная с первого дня года
IW неделя, начиная с понедельника
W неделя, начиная с первого дня месяца
DAY,DY,D первый день недели, воскресенье
MONTH,MON,MM,RM месяц
CC,SCC век
DDD,DD,J день
HH,HH12,HH24 час
MI минута
Функции округляются. То есть дата 1 июля будет округлена до следующего года. 16 июля округляется до августа.
Функции даты
add_months ( date, integer ) → date
Возвращает дату плюс n месяцев.
Пример:
add_months(date '2005-05-31',1) → 2005-06-30
last_day ( date ) → date
Возвращает последний день месяца на основе значения даты.
Пример:
last_day(date '2005-05-24') → 2005-05-31
next_day ( date, text ) → date
Возвращает первый день недели, который больше значения даты.
Пример:
next_day(date '2005-05-24', 'monday') → 2005-05-30
next_day ( date, integer ) → date
То же, что и выше. Второй аргумент должен быть 1..7 и интерпретироваться как воскресенье..суббота.
Пример:
next_day(date '2005-05-24', 1) → 2005-05-30
months_between ( date, date ) → numeric
Возвращает количество месяцев между датой1 и датой2. Если вычисляется дробный месяц, функция months_between вычисляет дробь на основе 31-дневного месяца.
Пример:
months_between(date '1995-02-02', date '1995-01-01') → 1.0322580645161
trunc ( date, text ) → date
Усекает дату в соответствии с указанным форматом.
Пример:
trunc(date '2005-07-12', 'iw') → 2005-07-11
round ( date, text ) → date
Округляет дату в соответствии с указанным форматом.
Пример:
round(date '2005-07-12', 'yyyy') → 2006-01-01
to_date ( text ) → timestamp
Приводит вводимый текст к временной метке. GUC orafce.nls_date_format используется для указания формата входного текста для этой функции. Если значение оставлено пустым или установлено как default (формат по умолчанию), тогда введите текстовый формат в соответствии с настройкой стиля даты GUC QHB.
Примеры:
orafce.nls_date_format value to DEFAULT
to_date('2014-05-19 17:23:53+5:30') -> 2014-05-19 17:23:53
orafce.nls_date_format='YYYY-MMDD HH24:MI:SS'
to_date('2014-0519 17:23:53+5:30') -> 2014-05-19 17:23:53
to_date (text, text) → timestamp
Приводит вводимый текст с заданным форматом к временной метке. GUC orafce.orafce_emit_error_on_date_bug используется для указания того, будет ли выводиться сообщение об ошибке, если значение даты попадает в область дефекта дат в Oracle. Этот дефект появляется в датах до 1582-10-05 при использовании формата 'J' ('J2299159') и до 1100-03-01 с остальными форматами. По умолчанию об ошибке сообщается; чтобы отключить это поведение, установите в orafce.orafce_emit_error_on_date_bug значение off.
SELECT oracle.to_date('112012', 'J');
ERROR: Dates before 1582-10-05 ('J2299159') cannot be verified due to a bug in Oracle.
-- ОШИБКА: Даты до 1582-10-05 ('J2299159') нельзя проверить из-за дефекта в Oracle.
SELECT oracle.to_date('1003-03-15', 'yyyy-mm-dd');
ERROR: Dates before 1100-03-01 cannot be verified due to a bug in Oracle.
-- ОШИБКА: Даты до 1100-03-01 нельзя проверить из-за дефекта в Oracle
SET orafce.oracle_compatibility_date_limit TO off;
SELECT oracle.to_date('112012', 'J');
to_date
------------------------
4407-07-30 00:00:00 BC
(1 row)
SELECT oracle.to_date('1003/03/15', 'yyyy/mm/dd');
to_date
---------------------
1003-03-15 00:00:00
(1 row)
Тип данных oracle.date
Этот модуль содержит реализацию совместимого с Oracle типа данных date, oracle.date, и функций, использующих тип данных date, таких как oracle.add_months, oracle.last_day(), oracle.next_day(), oracle.months_between() и т. д.
Пример:
SET search_path TO oracle,"$user", public, pg_catalog;
CREATE TABLE oracle_date(col1 date);
INSERT INTO oracle_date values('2014-06-24 12:12:11'::date);
SELECT * FROM oracle_date;
col1
---------------------
2014-06-24 12:12:11
(1 row)
Функции oracle.date
oracle.add_months ( timestamp with time zone, integer ) → timestamp with time zone
Возвращает дату и время плюс n месяцев.
Пример:
oracle.add_months(oracle.date'2005-05-31 10:12:12',1) → 2005-06-30 10:12:12
oracle.last_day ( timestamp with time zone ) → timestamp with time zone
Возвращает последний день месяца на основе значения даты.
Пример:
oracle.last_day(oracle.date '2005-05-24 11:12:12') → 2005-05-31 11:12:12
oracle.next_day ( timestamp with time zone, text ) → timestamp with time zone
Возвращает первый день недели, который больше значения даты.
Пример:
oracle.next_day(oracle.date '2005-05-24 10:12:12', 'monday') → 2005-05-30 10:12:12
oracle.next_day ( timestamp with time zone, integer ) → timestamp with time zone
То же, что и выше. Второй аргумент должен быть 1..7 и интерпретироваться как воскресенье..суббота.
Пример:
oracle.next_day(oracle.date '2005-05-24 11:21:12', 1) → 2005-05-29 11:21:12
oracle.months_between ( timestamp with time zone, timestamp with time zone ) → numeric
Возвращает количество месяцев между временной меткой1 и временной меткой2. Если вычисляется дробный месяц, функция months_between вычисляет дробь на основе 31-дневного месяца.
Пример:
oracle.months_between(oracle.date '1995-02-02 10:00:00', oracle.date '1995-01-01 10:21:11') → 1.03225806451613
oracle.to_date ( text, text ) → timestamp without time zone
Возвращает временную метку без часового пояса.
Пример:
oracle.to_date('02/16/09 04:12:12', 'MM/DD/YY HH24:MI:SS') → 2009-02-16 04:12:12
oracle.to_date ( text ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('16.02.09 04:12:12') → 2009-02-16 04:12:12
oracle.sysdate() → timestamp with time zone
Возвращает временную метку оператора в часовом поясе сервера (orafce.timezone).
Пример:
oracle.sysdate() → 2015-12-09 17:47:56
oracle.dbtimezone() → timezone
Возвращает часовой пояс сервера — эмулированный через orafce.timezone.
Пример:
oracle.dbtimezone() → GMT
oracle.sessiontimezone() → timezone
Возвращает часовой пояс сеанса — текущий часовой пояс QHB.
Пример:
oracle.sessiontimezone() → Europe/Prague
oracle.sys_extract_utc ( timestamp with timezone ) → timestamp with time zone
Возвращает временную метку в часовом поясе UTC.
Пример:
oracle.sys_extract_utc(current_timestamp)
oracle.sys_extract_utc ( oracle.date ) → timestamp with time zone
Возвращает временную метку в часовом поясе UTC; если часовой пояс не указан, используется часовой пояс сеанса (текущий часовой пояс QHB).
Пример:
oracle.sys_extract_utc(oracle.date '2005-05-24 11:21:12', 1) -> 2005-05-24 09:21:12
oracle.to_char ( timestamp ) → nls_date_format
Возвращает временную метку в формате nls_date_format.
Примеры:
orafce.nls_date_format='YY-MonDD HH24:MI:SS'
oracle.to_char(to_date('14-Jan08 11:44:49+05:30')) -> 14-Jan08 11:44:49
orafce.nls_date_format='YY-MonDD HH24:MI:SS'
oracle.to_char(oracle.to_date('21052014 12:13:44+05:30','DDMMYYYY HH24:MI:SS')) -> 14-May21 12:13:44
Операторы oracle.date
oracle. + ( oracle.date, smallint ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') + 9::smallint → 2014-07-11 10:08:55
oracle. + ( oracle.date, integer ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') + 9::integer → 2014-07-11 10:08:55
oracle. + ( oracle.date, bigint ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') + 9::bigint → 2014-07-11 10:08:55
oracle. + ( oracle.date, numeric ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') + 9::numeric → 2014-07-11 10:08:55
oracle. - ( oracle.date, smallint ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') - 9::smallint → 2014-06-23 10:08:55
oracle. - ( oracle.date, integer ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') - 9::integer → 2014-06-23 10:08:55
oracle. - ( oracle.date, bigint ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') - 9::bigint → 2014-06-23 10:08:55
oracle. - ( oracle.date, numeric ) → oracle.date
Возвращает oracle.date.
Пример:
oracle.to_date('2014-07-02 10:08:55','YYYY-MM-DD HH:MI:SS') - 9::numeric -> 2014-06-23 10:08:55
oracle. - ( oracle.date, oracle.date ) → double precision
Возвращает double precision.
Пример:
oracle.to_date('2014-07-17 11:10:15', 'yyyy-mm-dd hh24:mi:ss') - oracle.to_date('2014-02-01 10:00:00', 'yyyy-mm-dd hh24:mi:ss') → 166.048785
Вам нужно установить search_path в oracle, "$user", public, pg_catalog,
потому что такие функции, как oracle.add_months, oracle.last_day,
oracle.next_day и oracle.months_between, устанавливаются бок о бок с
функциями pg_catalog.add_months, pg_catalog.last_day,
pg_catalog.next_day и pg_catalog.months_between.
«Двойная» таблица
QHB не нуждается в «двойной» таблице Oracle, но поскольку она
интенсивно используется пользователями Oracle, она была добавлена в orafce.
Эта таблица находится в схеме oracle. Обычно имеет смысл разрешить к ней
широкий доступ, поэтому следует добавить эту схему в конфигурацию search_path
(например, search_path = 'oracle, pg_catalog, "$user", public' в qhb.conf).
Пакет dbms_output
QHB отправляет информацию клиенту через RAISE NOTICE. Oracle использует dbms_output.put_line(). Это работает иначе, чем RAISE NOTICE. В Oracle имеется очередь сеанса, функция put_line() добавляет строку в очередь, а функция get_line() читает из очереди. Если установлен флаг serveroutput, то клиент по всем операторам SQL читает очередь. Вы можете выполнить:
SELECT dbms_output.enable();
SELECT dbms_output.put_line('first_line');
SELECT dbms_output.put_line('next_line');
SELECT * FROM dbms_output.get_lines(0);
или
SELECT dbms_output.enable();
SELECT dbms_output.serveroutput('t');
SELECT dbms_output.put_line('first_line');
Этот пакет содержит следующие функции: enable(), disable(), serveroutput(), put(), put_line(), new_line(), get_line(), get_lines(). Очередь пакетов реализуется в локальной памяти сеанса.
Пакет utl_file
Этот пакет позволяет программам PL/pgSQL читать и записывать любые файлы, доступные с сервера. Каждый сеанс может открыть максимум десять файлов, а максимальный размер строки составляет 32 КБ. Этот пакет содержит следующие функции:
utl_file.fclose ( файл utl_file.file_type)
Закрывает файл.
utl_file.fclose_all()
Закрывает все файлы.
utl_file.fcopy (_ располож_исходн_ text, имя_исх_файла text, располож_цели text, имя_целев_файла text [, начальн_строка text ] [, конечн_строка text ] )
Копирует текстовый файл.
utl_file.fflush ( файл utl_file.file_type )
Сбрасывает на диск все данные из буферов.
utl_file.fgetattr ( расположение text, имя_файла text )
Выводит атрибуты файла.
utl_file.fopen ( расположение text, имя_файла text, режим_файла text [, макс_размер_строки int ] [, кодировка name ] ) → utl_file.file_type
Открывает файл.
utl_file.fremove ( расположение text, имя_файла text )
Удаляет файл.
utl_file.frename ( расположение text, имя_файла text, целевой_каталог text, целевой_файл text [, перезаписать bool ] )
Переименовывает файл.
utl_file.get_line ( файл utl_file.file_type) → text
Считывает одну строку из файла.
utl_file.get_nextline ( файл utl_file.file_type) → text
Считывает одну строку из файла или возвращает NULL.
utl_file.is_open ( файл utl_file.file_type) → bool
Возвращает true, если файл открыт.
utl_file.new_line ( файл utl_file.file_type [, строки int ] )
Помещает в файл несколько новых строковых символов.
utl_file.put ( файл utl_file.file_type, буфер text )
Помещает содержимое буфера в файл.
utl_file.put_line ( файл utl_file.file_type, буфер text )
Помещает строку из буфера в файл.
utl_file.putf ( файл utl_file.file_type, буфер text, формат [, арг1 text ] [, арг2 text ] [..] [, арг5 text ] )
Помещает форматированный текст в файл.
utl_file.tmpdir()
Выводит путь к временному каталогу.
Поскольку QHB не поддерживает вызов по ссылке, некоторые функции немного отличаются: fclose и get_line.
do $$
declare f utl_file.file_type;
begin
f := utl_file.fopen('/tmp', 'sample.txt', 'r');
<<readl>>
loop
begin
raise notice '%', utl_file.get_line(f);
exception
when no_data_found then
exit readl;
end;
end loop;
f := utl_file.fclose(f);
end;
$$;
или второй (со специальной функцией QHB get_nextline)
do $$
declare
f utl_file.file_type;
line text;
begin
f := utl_file.fopen('/tmp', 'sample.txt', 'r');
loop
line := utl_file.get_nextline(f);
exit when line is NULL;
raise notice '%', line;
end loop
exception
when others then
perform utl_file.fclose_all();
end;
$$;
Перед использованием пакета вы должны установить таблицу utl_file.utl_file_dir. Она содержит все разрешенные каталоги без завершающего символа (/ или \). На платформе WinNT пути должны каждый раз заканчиваться символом \.
Записи каталога могут быть названы (второй столбец в таблице utl_file.utl_file_dir). Параметр расположение может быть либо именем каталога, либо путем к словарю. Расположение сначала интерпретируется и проверяется как имя каталога. Если каталог не найден (во 2-м столбце), то расположение интерпретируется и проверяется как путь.
Функции из пакета utl_file (схема в QHB) требуют доступа к
таблице utl_file.utl_file_dir. Этот факт можно использовать для контроля
того, могут ли пользователи использовать эти функции или нет. Значение по
умолчанию — READ для public. INSERT и UPDATE может выполнять только
привилегированный пользователь (суперпользователь). Таким образом, обычный
пользователь может вызывать функции из этого пакета, но не может изменять список
безопасных каталогов (содержимое таблицы utl_file.utl_file_dir). Содержимое
этой таблицы видно для public (или должно быть видно для пользователей,
использующих функции из этого пакета).
Пакет dbms_sql
Данный пакет — реализация Oracle API пакета DBMS_SQL.
Он не обеспечивает полной совместимости, но должен уменьшить работу, необходимую для успешной миграции.
Внимание: архитектура QHB отличается от архитектуры Oracle. PL/pgSQL выполняется в том же контексте, что и механизм SQL. Тогда нет никакой причины использовать шаблоны Oracle, такие как массовый сбор и итерация по сбору в QHB, для получения хорошей производительности. Этот код предназначен для сокращения работы, связанной с переносом некоторых приложений с Oracle на QHB, и может работать хорошо. Но никакого преимущества в производительности по сравнению со встроенными операторами PL/pgSQL не будет. Эмуляция API Oracle требует дополнительных ресурсов памяти и ЦП, которые могут быть значительными при больших объемах данных.
Функциональность
Это расширение реализует подмножество интерфейса Oracle dbms_sql. Целью этого расширения является не совместимость с Oracle: оно предназначено для сокращения объема работы, связанной с миграцией приложений Oracle на QHB. Поддерживаются некоторые базовые функции массового DML:
DO $$
DECLARE
c int;
a int[];
b varchar[];
ca numeric[];
BEGIN
c := dbms_sql.open_cursor();
call dbms_sql.parse(c, 'insert into foo values(:a, :b, :c)');
a := ARRAY[1, 2, 3, 4, 5];
b := ARRAY['Ahoj', 'Nazdar', 'Bazar'];
ca := ARRAY[3.14, 2.22, 3.8, 4];
call dbms_sql.bind_array(c, 'a', a, 2, 3);
call dbms_sql.bind_array(c, 'b', b, 3, 4);
call dbms_sql.bind_array(c, 'c', ca);
raise notice 'inserted rows %d', dbms_sql.execute(c);
END;
$$;
DO $$
DECLARE
c int;
a int[];
b varchar[];
ca numeric[];
BEGIN
c := dbms_sql.open_cursor();
call dbms_sql.parse(c, 'select i, ''Ahoj'' || i, i + 0.003 from generate_series(1, 35) g(i)');
call dbms_sql.define_array(c, 1, a, 10, 1);
call dbms_sql.define_array(c, 2, b, 10, 1);
call dbms_sql.define_array(c, 3, ca, 10, 1);
perform dbms_sql.execute(c);
while dbms_sql.fetch_rows(c) > 0
loop
call dbms_sql.column_value(c, 1, a);
call dbms_sql.column_value(c, 2, b);
call dbms_sql.column_value(c, 3, ca);
raise notice 'a = %', a;
raise notice 'b = %', b;
raise notice 'c = %', ca;
end loop;
call dbms_sql.close_cursor(c);
END;
$$;
Имеется функция dbms_sql.describe_columns_f, похожая на процедуру dbms_sql.describe_columns. Обратите внимание, что идентификаторы типов относятся к системе типов QHB. Значения не конвертируются в числа Oracle.
DO $$
DECLARE
c int;
r record;
d dbms_sql.desc_rec;
BEGIN
c := dbms_sql.open_cursor();
call dbms_sql.parse(c, 'select * from pg_class');
r := dbms_sql.describe_columns(c);
raise notice '%', r.col_cnt;
foreach d in array r.desc_t
loop
raise notice '% %', d.col_name, d.col_type::regtype;
end loop;
call dbms_sql.close_cursor(c);
END;
$$;
DO $$
DECLARE
c int;
n int;
d dbms_sql.desc_rec;
da dbms_sql.desc_rec[];
BEGIN
c := dbms_sql.open_cursor();
call dbms_sql.parse(c, 'select * from pg_class');
call dbms_sql.describe_columns(c, n, da);
raise notice '%', n;
foreach d in array da
loop
raise notice '% %', d.col_name, d.col_type::regtype;
end loop;
call dbms_sql.close_cursor(c);
END;
$$;
Пакет dbms_pipe
Этот пакет является эмуляцией пакета Oracle dbms_pipe. Он обеспечивает взаимодействие между сеансами. Вы можете отправлять и читать любое сообщение с ожиданием или без него, просмотреть список активных каналов, установить канал как частный или общедоступный и использовать явные или неявные каналы.
Максимальное количество каналов: 50.
Для отправки сообщений используется разделяемая память.
Ниже приведен пример:
-- Сеанс A
SELECT dbms_pipe.create_pipe('my_pipe',10,true); -- явное создание канала
SELECT dbms_pipe.pack_message('neco je jinak');
SELECT dbms_pipe.pack_message('anything is else');
SELECT dbms_pipe.send_message('my_pipe',20,0); -- изменение предела и передача без ожидания
SELECT * FROM dbms_pipe.db_pipes; -- список текущих каналов
-- Сеанс B
SELECT dbms_pipe.receive_message('my_pipe',1); -- ожидание для сообщения максимум 1 секунда
SELECT dbms_pipe.next_item_type(); -- -> 11, текст
SELECT dbms_pipe.unpack_message_text();
SELECT dbms_pipe.next_item_type(); -- -> 11, текст
SELECT dbms_pipe.unpack_message_text();
SELECT dbms_pipe.next_item_type(); -- -> 0, больше элементов нет
SELECT dbms_pipe.remove_pipe('my_pipe');
Однако есть некоторые отличия от Oracle:
- предел для каналов не в байтах, а в элементах в канале
- можно отправить сообщение без ожидания
- можно отправлять пустые сообщения
- next_item_type знает о timestamp (тип 13)
- QHB не знает о типе raw, вместо этого используйте bytea
Пакет dbms_alert
Еще одно средство межпроцессного взаимодействия.
-- Сеанс A
SELECT dbms_alert.register('boo');
SELECT * FROM dbms_alert.waitany(10);
-- Сеанс B
SELECT dbms_alert.register('boo');
SELECT * FROM dbms_alert.waitany(10);
-- Сеанс C
SELECT dbms_alert.signal('boo','Nice day');
Пакет PLVdate
Этот модуль содержит некоторые функции для работы с рабочими днями из пакета PLVdate. Подробную документацию можно найти в библиотеке PLVision. Этот пакет является мультикультурным, но конфигурации по умолчанию предназначены только для европейских стран (см. исходный код).
Вы должны определить свои собственные нерабочие дни (максимум 50 дней) и собственные праздники (максимум 30 дней). Выходной день — это любой нерабочий день, который одинаков каждый год. Например, Рождество в западных странах.
Функции
plvdate.add_bizdays ( дата date, число_дней int ) → date
Выводит дату, созданную путем добавления n рабочих дней к заданной.
plvdate.nearest_bizday ( дата date ) → date
Выводит рабочую дату, ближайшую к заданной дате, определяемой пользователем.
plvdate.next_bizday ( дата date ) → date
Выводит следующую рабочую дату после заданной даты, определяемой пользователем.
plvdate.bizdays_between ( дата1 date, дата2 date ) → int
Выводит количество рабочих дней между двумя заданными датами.
plvdate.prev_bizday ( дата date ) → date
Выводит предыдущую рабочую дату от заданной даты.
plvdate_isbizday ( date ) → bool
Возвращает true, если заданная дата является рабочим днем.
plvdate.set_nonbizday ( день_недели varchar )
Устанавливает заданный день недели как нерабочий.
plvdate.unset_nonbizday ( день_недели varchar )
Отменяет установку заданного дня недели как нерабочего.
plvdate.set_nonbizday ( дата date )
Устанавливает заданный день как нерабочий.
plvdate.unset_nonbizday ( дата date )
Отменяет установку заданного дня как нерабочего.
plvdate.set_nonbizday ( дата date, повторять bool )
Устанавливает заданный день как нерабочий; если параметр повторять равен true, то день будет нерабочим каждый год.
plvdate.unset_nonbizday ( дата date, повторять bool )
Отменяет установку заданного дня как нерабочего; если параметр повторять равен true, то установка отменяется и на последующие годы.
plvdate.use_easter()
Пасхальное воскресенье и Пасхальный понедельник будут выходными.
plvdate.unuse_easter()
Пасхальное воскресенье и Пасхальный понедельник не будут выходными.
plvdate.use_easter ( использовать bool )
Если true, то Пасхальное воскресенье и Пасхальный понедельник будут выходными.
plvdate.using_easter() → bool
Возвращает true, если Пасхальное воскресенье и Пасхальный понедельник являются выходными.
plvdate.use_great_friday()
Страстная пятница будет выходным.
plvdate.unuse_easter()
Страстная пятница не будет выходным.
plvdate.use_easter ( использовать bool )
Если true, то Страстная пятница будет выходным.
plvdate.using_easter() → bool
Возвращает true, если Страстная пятница является выходным.
plvdate.include_start()
Включает в расчет bizdays_between дату начала.
plvdate.noinclude_start()
Исключает из расчета bizdays_between дату начала.
plvdate.include_start ( включить bool )
Если true, то в расчет bizdays_between включается дата начала.
plvdate.include_start() → bool
Возвращает true, если в расчет bizdays_between включена дата начала.
plvdate.default_holidays ( varchar )
Загружает конфигурации по умолчанию. На данный момент доступны следующие конфигурации: Чехия, Германия, Австрия, Польша, Словакия, Россия, Великобритания и США. Конфигурация содержит только общие праздники для всех регионов. Свой региональный праздник можно добавить с помощью plvdate.set_nonbizday(nonbizday, true).
Пример:
qhb=# select plvdate.default_holidays('czech');
default_holidays
-----------------
(1 row)
qhb=# select to_char(current_date, 'day'),
plvdate.next_bizday(current_date),
to_char(plvdate.next_bizday(current_date),'day');
to_char | next_bizday | to_char
----------+-------------+-----------
saturday | 2006-03-13 | monday
(1 row)
Изменение для неевропейской среды:
SELECT plvdate.unset_nonbizday('saturday');
SELECT plvdate.unset_nonbizday('sunday');
SELECT plvdate.set_nonbizday('friday');
SELECT plvdate.set_nonbizday('2006-05-19', true);
SELECT plvdate.unuse_easter();
Пакет PLVstr и PLVchr
Этот пакет содержит несколько полезных строковых и символьных функций. Каждая функция поддерживает положительные и отрицательные смещения, т. е. смещение как от начала, так и от конца строки. Например:
plvstr.left('abcdef',2) -> ab
plvstr.left('abcdef',-2) -> abcd
plvstr.substr('abcdef',1,1) -> a
plvstr.substr('abcdef',-1,1) -> f
plvstr.substr('abcde',-2,1) -> d
Список функций:
plvstr.normalize ( строка text )
Нормализует заданную строку: заменяет пустые символы на пробел и несколько пробелов на один.
plvstr.is_prefix ( строка text, префикс text, cs bool ) → bool
Возвращает true, если заданный префикс является префиксом указанной строки.
plvstr.is_prefix ( строка text, префикс text ) → bool
Возвращает true, если заданный префикс является префиксом указанной строки.
plvstr.is_prefix ( строка int, префикс int ) → bool
Возвращает true, если заданный префикс является префиксом указанной строки.
plvstr.is_prefix ( строка bigint, префикс bigint ) → bool
Возвращает true, если заданный префикс является префиксом указанной строки.
plvstr.substr ( строка text, начало int, длина int ) → text
Извлекает из заданной строки подстроку указанной длины (в символах), начиная с символа на позиции начало.
plvstr.substr ( строка text, начало int ) → text
Извлекает из заданной строки подстроку, начиная с символа на позиции начало и до конца строки.
plvstr.instr ( строка text, шаблон text, начало int, n int ) → text
Ищет n-й заданный шаблон в указанной строке, начиная с символа на позиции начало.
plvstr.instr ( строка text, шаблон text, начало int ) → text
Ищет заданный шаблон в указанной строке, начиная с символа на позиции начало.
plvstr.instr ( строка text, шаблон text ) → text
Ищет заданный шаблон в указанной строке.
plvstr.lpart ( строка text, раздел text, начало int, n int, всё_если_не_найдено bool ) → text
Возвращает левую часть строки. Если параметр всё_если_не_найдено равен true, то в случае отсутствия искомого возвращается вся строка.
plvstr.lpart ( строка text, раздел text, начало int, n int ) → text
Возвращает левую часть строки.
plvstr.lpart ( строка text, раздел text, начало int ) → text
Возвращает левую часть строки.
plvstr.lpart ( строка text, раздел text ) → text
Возвращает левую часть строки.
plvstr.rpart ( строка text, раздел text, начало int, n int, всё_если_не_найдено bool ) → text
Возвращает правую часть строки. Если параметр всё_если_не_найдено равен true, то в случае отсутствия искомого возвращается вся строка.
plvstr.rpart ( строка text, раздел text, начало int, n int ) → text
Возвращает правую часть строки.
plvstr.rpart ( строка text, раздел text, начало int ) → text
Возвращает правую часть строки.
plvstr.rpart ( строка text, раздел text ) → text
Возвращает правую часть строки.
plvstr.lstrip ( строка text, подстрока text, число int ) → text
Удаляет символы с начала строки.
plvstr.lstrip ( строка text, подстрока text ) → text
Удаляет символы с начала строки.
plvstr.rstrip ( строка text, подстрока text, число int ) → text
Удаляет символы с конца строки.
plvstr.rstrip ( строка text, подстрока text ) → text
Удаляет символы с конца строки.
plvstr.rvrs ( строка text, начало int, конец int ) → text
Реверсирует строку или часть строки.
plvstr.rvrs ( строка text, начало int ) → text
Реверсирует строку или часть строки.
plvstr.rvrs ( строка text ) → text
Реверсирует строку или часть строки.
plvstr.left ( строка text, n int ) → text
Возвращает первые n символов. Можно использовать отрицательный n.
plvstr.right ( строка text, n int ) → text
Возвращает последние n символов. Можно использовать отрицательный n.
plvstr.swap ( строка text, замена text, начало int, длина int ) → text
Заменяет заданной заменой указанной длины (в символах) подстроку в указанной строке, начиная с символа на позиции начало.
plvstr.swap ( строка text, замена text ) → text
Заменяет заданной заменой подстроку в указанной строке.
plvstr.betwn ( строка text, начало int, конец int, включительно bool ) → text
Ищет строку между заданными начальным и конечным символами. Если параметр включительно равен true, граничные символы включаются в поиск.
plvstr.betwn ( строка text, начало int, конец int, начало_на_n int, конец_на_n int, включительно bool, искать_до_конца bool ) → text
Ищет строку между заданными начальным и конечным символами. Если параметр включительно равен true, граничные символы включаются в поиск. Если параметр искать_до_конца равен true, поиск ведется до конца строки.
plvstr.betwn ( строка text, начало int, конец int ) → text
Ищет строку между заданными начальным и конечным символами.
plvstr.betwn ( строка text, начало int, конец int, начало_на_n int, конец_на_n int ) → text
Ищет строку между заданными начальным и конечным символами.
plvchr.nth ( строка text, n int ) → text
Возвращает n-й символ в строке.
plvchr.first ( строка text ) → text
Возвращает первый символ в строке.
plvchr.last ( строка text ) → text
Возвращает последний символ в строке.
plvchr.is_blank ( c int )
Это пустой символ.
plvchr.is_blank ( c text )
Это пустой символ.
plvchr.is_digit ( c int )
Это цифра.
plvchr.is_digit ( c text )
Это цифра.
plvchr.is_quote ( c int )
Это кавычка.
plvchr.is_quote ( c text )
Это кавычка.
plvchr.is_other ( c int )
Это другое.
plvchr.is_other ( c text )
Это другое.
plvchr.is_letter ( c int )
Это буква.
plvchr.is_letter ( c text )
Это буква.
plvchr.char_name ( c text )
Возвращает имя символа в код ASCII как varchar.
plvchr.quoted1 ( строка text )
Текст в кавычках вида «'».
plvchr.quoted2 ( строка int )
Текст в кавычках вида «"».
plvchr.stripped ( строка text, символы text )
Очищает строку от всех вхождений заданных символов.
Пакет PLVsubst
Пакет PLVsubst выполняет замену строк на основе замещающего ключевого слова.
plvsubst.string ( шаблон text, значения text[] )
Сканирует строку на предмет всех вхождений замещаемого ключевого слова и заменяет его следующим значением из списка замещающих значений.
plvsubst.string ( шаблон text, значения text[], замена text )
Сканирует строку на предмет всех вхождений замещаемого ключевого слова и заменяет его следующим значением из списка замещающих значений.
plvsubst.string ( шаблон text, значения text[], разделитель text )
Сканирует строку на предмет всех вхождений замещаемого ключевого слова и заменяет его следующим значением из списка замещающих значений.
plvsubst.string ( шаблон text, значения text[], разделитель text замена text )
Сканирует строку на предмет всех вхождений замещаемого ключевого слова и заменяет его следующим значением из списка замещающих значений.
plvsubst.setsubst ( строка text )
Устанавливает замещаемое ключевое слово в значение по умолчанию (%s).
plvsubst.subst()
Выводит замещаемое ключевое слово.
Примеры:
SELECT plvsubst.string('My name is %s %s.', ARRAY['Pavel','Stěhule']);
_`строка`_
--------------------------
My name is Pavel Stěhule.
(1 row)
SELECT plvsubst.string('My name is %s %s.', 'Pavel,Stěhule');
_`строка`_
--------------------------
My name is Pavel Stěhule.
(1 row)
SELECT plvsubst.string('My name is $$ $$.', 'Pavel|Stěhule','|','$$');
_`строка`_
--------------------------
My name is Pavel Stěhule.
(1 row)
Пакет DBMS_utility
dms_utility.format_call_stack()
Возвращает отформатированную строку с содержимым стека вызовов.
qhb=# select foo2();
foo2
---------------------------------
----- Call Stack -----
line object
number statement name
1 return function foo
1 return function foo1
1 return function foo2
(1 row)
Пакет PLVlex
Этот пакет несовместим с оригинальным PLVlex.
plvlex.tokens ( строка text, пропускать_пробелы bool, уточненные_имена bool )
Возвращает таблицу лексических элементов в строке.
qhb=# select * from
plvlex.tokens('select * from a.b.c join d ON x=y', true, true);
pos | token | code | class | separator | mod
----+--------+------+---------+-----------+------
0 | select | 527 | KEYWORD | |
7 | * | 42 | OTHERS | | self
9 | from | 377 | KEYWORD | |
25 | a.b.c | | IDENT | |
20 | join | 418 | KEYWORD | |
25 | d | | IDENT | |
27 | on | 473 | KEYWORD | |
30 | x | | IDENT | |
31 | = | 61 | OTHERS | | self
32 | y | | IDENT | |
(10 rows)
ВНИМАНИЕ!
Коды ключевых слов могут меняться от версии к версии QHB!
Пакет DBMS_ASSERT
Этот пакет защищает пользовательский ввод от SQL-инъекций.
dbms_assert.enquote_literal ( varchar ) → varchar
Добавляет открывающие и закрывающие кавычки, проверяет, что все апострофы сопоставлены с соседними апострофами.
dbms_assert.enquote_name ( varchar [, boolean ] ) → varchar
Заключает имя в двойные кавычки. Необязательный второй параметр переводит имя в нижний регистр. Внимание — в Oracle второй параметр переводит имя в верхний регистр.
dbms_assert.noop ( varchar ) → varchar
Возвращает значение без какой-либо проверки.
dbms_assert.qualified_sql_name ( varchar ) → varchar
Эта функция удостоверяется, что входная строка является уточненным именем SQL.
dbms_assert.schema_name ( varchar ) → varchar
Эта функция удостоверяется, что входная строка является существующим именем схемы.
dbms_assert.simple_sql_name ( varchar ) → varchar
Эта функция удостоверяется, что входная строка является простым именем SQL.
dbms_assert.object_name ( varchar ) → varchar
Эта функция удостоверяется, что входная строка является уточненным идентификатором SQL для существующего объекта SQL.
Пакет PLUnit
Этот пакет содержит некоторые функции утверждения.
plunit.assert_true ( bool [, varchar ] )
Утверждает, что условие истинно.
plunit.assert_false ( bool [, varchar ] )
Утверждает, что условие ложно.
plunit.assert_null ( anyelement [, varchar ] )
Утверждает, что фактическое значение является NULL.
plunit.assert_not_null ( anyelement [, varchar ] )
Утверждает, что фактическое значение не является NULL.
plunit.assert_equals ( anyelement, anyelement [, double precision ] [, varchar ] )
Утверждает, что ожидаемое и фактическое значения равны.
plunit.assert_not_equals (anyelement, anyelement [, double precision ] [, varchar ] )
Утверждает, что ожидаемое и фактическое значения не равны.
plunit.fail ( [ varchar ] )
Эту функцию можно использовать, чтобы с помощью предоставленного сообщения заставить тестовую процедуру немедленно завершиться ошибкой.
Пакет DBMS_random
dbms_random.initialize(int)
Инициализирует пакет с величиной рандомизации.
dbms_random.normal()
Возвращает случайные числа со стандартным распределением Гаусса.
dbms_random.random()
Возвращает случайное число из диапазона -2^31 .. 2^31.
dbms_random.seed(int)
Возвращает величину рандомизации.
dbms_random.seed(text)
Сбрасывает величину рандомизации.
dbms_random.string(opt text(1), длина int)
Создает случайную строку.
dbms_random.terminate()
Завершает пакет (ничего не делает в QHB).
dbms_random.value()
Возвращает случайное число из диапазона [0.0 - 1.0).
dbms_random.value ( low double precision, high double precision )
Возвращает случайное число из диапазона [low - high).
Другие функции
Этот модуль содержит реализацию следующих функций: concat, nvl, nvl2, lnnvl, decode, greatest, least, bitand, nanvl, sinh, cosh, tanh, oracle.substr и oracle.mod.
oracle.substr ( строка text, начало int, длина int )
Функция substring, совместимая с Oracle.
oracle.substr ( строка text, начало int )
Функция substring, совместимая с Oracle.
oracle.substr ( строка numeric, начало numeric )
Функция substring, совместимая с Oracle.
oracle.substr ( строка numeric, начало numeric, длина numeric )
Функция substring, совместимая с Oracle.
oracle.substr ( строка varchar, начало numeric )
Функция substring, совместимая с Oracle.
oracle.substr ( строка varchar, начало numeric, длина numeric )
Функция substring, совместимая с Oracle.
oracle.lpad ( строка, длина[,заполнитель ] )
Функция lpad, совместимая с Oracle.
oracle.rpad ( строка, длина[,заполнитель ] )
Функция rpad, совместимая с Oracle.
oracle.ltrim ( строка text [, символы text ] )
Функция ltrim, совместимая с Oracle.
oracle.rtrim ( строка text [, символы text ] )
Функция rtrim, совместимая с Oracle.
oracle.btrim ( text [, символы text ] )
Функция btrim, совместимая с Oracle.
oracle.length ( строка char )
Функция length, совместимая с Oracle.
oracle.listagg ( строка text [, разделитель text ] )
Агрегирует значения в список.
oracle.wm_concat ( строка text )
Агрегирует значения в список через запятую.
oracle.median(float4)
Вычисляет медиану.
oracle.median(float8)
Вычисляет медиану.
oracle.to_number(text)
Преобразует строку в число.
oracle.to_number(numeric)
Преобразует строку в число.
oracle.to_number(numeric,numeric)
Преобразует строку в число.
public.to_multi_byte(text)
Преобразует все однобайтовые символы в соответствующие им многобайтовые символы.
public.to_single_byte(text)
Преобразует все многобайтовые символы в соответствующие им однобайтовые символы.
oracle.greatest(anyelement, anyelement[])
Функция greatest, совместимая с Oracle; при вводе NULL возвращает NULL.
oracle.least(anyelement, anyelement[])
Функция least, совместимая с Oracle; при вводе NULL возвращает NULL.
oracle.mod(int, int)
Функция mod, совместимая с Oracle; если второй параметр равен нулю, возвращает первый параметр.
oracle.remainder(int, int)
Возвращает остаток от деления числа на другое число.
oracle.remainder(numeric, numeric)
Возвращает остаток от деления числа на другое число.
oracle.sys_guid() → bytea
Возвращает 16 байт глобального уникального идентификатора.
Возможно, вам потребуется установить для параметра search_path значение
oracle, pg_catalog, "$user", public, поскольку функции oracle.substr,
oracle.lpad, oracle.rpad, oracle.ltrim, oracle.rtrim, oracle.btrim и
oracle.length устанавливаются бок о бок с функциями pg_catalog.substr,
pg_catalog.lpad, pg_catalog.rpad, pg_catalog.ltrim, pg_catalog.rtrim,
pg_catalog.btrim и pg_catalog.length соответственно.
Функции oracle.decode, oracle.greatest и oracle.least всегда должны начинаться с префикса имени схемы, даже если oracle стоит перед pg_catalog в search_path, потому что эти функции реализованы внутри парсера и анализатора QHB. Без имени схемы всегда будут использоваться внутренние функции.
Обратите внимание, что в случае lpad и rpad параметры строка и заполнитель могут иметь типы char, varchar, text, varchar2 или nvarchar2 (обратите внимание, что последние два типа предоставляются orafce). Символ заполнения по умолчанию представляет собой пробел половинной ширины. То же самое верно для ltrim, rtrim и btrim.
Обратите внимание, что у функции oracle.length есть ограничение, заключающееся в том, что она работает только с единицами символов, поскольку в QHB тип char поддерживает только семантику символов.
Функция oracle.substr с тремя аргументами может вернуть другой результат (NULL или пустую строку) в зависимости от значения переменной orafce.using_substring_zero_width_in_substr (oracle, warning_oracle, orafce, warning_orafce). Этот другой результат возвращается, только когда третий аргумент (длина) равен нулю. Значение переменной по умолчанию — warning_oracle, то есть выводится предупреждение и возвращается NULL.
Функция oracle.sys_guid()
Эта функция возвращает глобальный уникальный идентификатор. Она вызывает указанные функции из расширения uuid-ossp, а затем эта функция должна быть установлена до использования функции sys_guid. По умолчанию эта функция использует функцию uuid_generate_v1, но также можно использовать функции uuid_generate_v1mc и uuid_generate_v4 (путем установки функции orafce.sys_guid_source). Кроме того, oracle.sys_guid может использовать встроенную функцию gen_random_uuid. В этом случае расширение uuid-ossp не требуется.
Поддержка varchar2 и nvarchar2
Тип varchar2 от orafce реализует части спецификации базы данных Oracle, касающиеся varchar2:
-
Единица модификатора типа — «байты» (семантику символов см. в описании типа nvarchar2).
-
В отличие от varchar QHB, неявное приведение к varchar2 не усекает пробелы сверх заявленной максимальной длины.
-
При установке orafce.varchar2_null_safe_concat в true для этих типов можно использовать защищенный от NULL оператор
||. Это поведение очень похоже на Oracle.
ВНИМАНИЕ!
Если результатом является пустая строка, то результат равен NULL. По умолчанию это поведение отключено.
ВНИМАНИЕ!
Возможна несовместимость между Orafce 3.7 и более старыми выпусками. Функция operator теперь помечена как стабильная (ранее была неизменяемой). Невозможно создать функциональные индексы по стабильными или изменчивым выражениям.
-- защищенная от NULL конкатенация (по умолчанию отключено)
SELECT NULL || 'hello'::varchar2 || NULL;
SET orafce.varchar2_null_safe_concat TO true;
SELECT NULL || 'hello'::varchar2 || NULL;
Обратите внимание, что QHB не позволяет динамически указывать, как мы интерпретируем строки varchar. Она всегда интерпретирует их как «символьные» строки в соответствии с кодировкой базы данных. Таким образом, мы не можем одновременно поддерживать семантику байтов и символов для данного типа varchar в одной и той же базе данных. Мы решили реализовать семантику байтов, так как она используется в Oracle по умолчанию. Семантику символов см. в описании типа nvarchar2, который по умолчанию всегда реализует семантику символов.
Будьте осторожны при использовании вышеуказанного типа для хранения строк, состоящих из многобайтовых закодированных символов, где каждый символ может состоять из произвольного количества байтов.
nvarchar2 реализует следующее:
- Единица модификатора типа — «символы» (с использованием набора символов/ кодировки базы данных)
Используйте этот тип, если предпочтительна семантика символов.
Обратите внимание, что, в отличие от Oracle, в orafce типы varchar2 и nvarchar2 не налагают ограничение в 4000 байт на «объявленный» размер. На самом деле это то же самое, что и у varchar в QHB, размер которого составляет около 10 МБ (хотя теоретически varchar может хранить значения размером до 1 ГБ).
Некоторые строковые функции на основе байтов для использования со строками varchar2:
substrb(varchar2, int [, int])
Извлекает подстроку заданной длины (в байтах), начиная с заданной позиции байта (считая с единицы); если третий аргумент не указан, то считается длина до конца строки.
strposb(varchar2, varchar2)
Возвращает расположение указанной подстроки в заданной строке (считая с единицы).
lengthb(varchar2)
Возвращает длину (в байтах) заданной строки.
Триггеры
Oracle не делает различий между NULL и пустой строкой (когда значение используется как текст). Для QHB NULL и пустая строка являются разными значениями. Для простоты рекомендуется обеспечить (в базе данных QHB) использование только NULL (и не использовать пустые строки) или использование только пустых строк (и не использовать NULL) для столбцов текстового типа. Оба варианта имеют некоторые преимущества и недостатки.
Это можно обеспечить с помощью триггерных функций:
oracle.replace_empty_strings([raise_warnings boolean])
oracle.replace_null_strings([raise_warnings boolean])
Необязательный логический аргумент используется в качестве индикатора, поэтому эти функции должны выдавать предупреждение, когда внутри них была изменена строка.
CREATE TABLE test(id serial, name varchar, surname varchar);
CREATE TRIGGER test_trg
BEFORE INSERT OR UPDATE
ON test
FOR EACH ROW
EXECUTE PROCEDURE oracle.replace_empty_strings();
INSERT INTO test(name, surname) VALUES('', 'Stehule');
-- имя будет заменено на NULL
Эмулированные представления
- oracle.user_tab_columns
- oracle.user_tables
- oracle.user_cons_columns
- oracle.user_constraints
- oracle.product_component_version
- oracle.user_objects
- oracle.dba_segments