Эквивалент Oracle 'printf'
Есть ли эквивалент или альтернатива следующему?
SELECT mix_type || ' (' || mix_num || ')' as description
FROM acid_batch
WHERE mix_num < 10
Есть ли у Oracle что-то вроде форматирования в стиле printf?
SELECT printf("%s (%s)", mix_type, mix_num) as description,
FROM acid_batch
WHERE mix_num < 10
Ответы
Ответ 1
Нет встроенных функций Oracle, которые применяют строку форматирования таким образом. Хотя было бы легко написать пользовательскую функцию для этого конкретного примера, писать PL/SQL-версию printf было бы сложной задачей.
Если у вас есть частая потребность в этом, возможно, вы можете написать функцию Oracle, которая завершает вызов Java для более богатой среды обработки строк.
Ответ 2
Ближайшая стандартная аппроксимация printf для Oracle, о которой я могу думать, utl_lms.format_message. Однако он не будет работать в операциях SQL, то есть это нормально:
begin
dbms_output.put_line(
utl_lms.format_message('hello %s, the number is %d', 'world', 42)
);
end;
/
но это дает ORA-00902: неверная ошибка типа данных:
select utl_lms.format_message('hello %s, the number is %d', 'world', 42)
from dual
Ответ 3
Еще одна идея для вас: я нашел REPLACE полезным для такого рода вещей, особенно когда шаблон сложный:
SELECT REPLACE(REPLACE(
'%mix_type% (%mix_num%)' /*template*/
,'%mix_type%', mix_type)
,'%mix_num%' , mix_num ) as description,
FROM acid_batch
WHERE mix_num < 10
Единственным недостатком является то, что вам нужно добавить столько REPLACE(
, как есть заменяемые переменные, но, по крайней мере, вам нужно иметь только одну переменную, независимо от того, сколько раз она появляется в шаблоне.
(ПРИМЕЧАНИЕ. Нет особого значения для использования "%" в качестве разделителя, это просто личное соглашение - вы можете выбрать другой шаблон, например <mix_type>
или [mix_type]
)
Для этого конкретного экземпляра он выглядит как излишний, но в некоторых случаях он может сделать вещи намного проще, например:
template := 'bla bla %a% %b% %a%';
output := REPLACE(REPLACE(template
,'%a%', some_complex_expression)
,'%b%', b);
Сравните приведенное выше с:
output := 'bla bla ' || some_complex_expression || ' ' || b || ' ' || some_complex_expression;
Ответ 4
Я создал простой механизм шаблонов под названием ora_te (на GitHub) для Oracle SQL/PLSQL.
С его помощью ваша цель может быть достигнута следующими способами:
Неэффективная реализация с несколькими разборами строки шаблона:
with acid_batch as (
select rownum as mix_type, rownum + 2 as mix_num
from all_objects
where rownum < 10
)
--
SELECT pk_te.substitute('$1 ($2)', ty_p( mix_type, mix_num ) ) as description
FROM acid_batch
WHERE mix_num < 10;
Эффективная реализация с однократной компиляцией (разбор):
with acid_batch as (
select rownum as mix_type, rownum + 2 as mix_num
from all_objects
where rownum < 10
),
--
o as (
select ty_te.compile_numbered( '$1 ($2)' ) te from dual
)
SELECT pk_te.substitute( o.te, ty_p( mix_type, mix_num ) ) as description
FROM acid_batch, o
WHERE mix_num < 10;
Кстати, он также поддерживает именованные заполнители.
Ответ 5
Вы можете разрешить его при выборе.
SELECT mix_type || '(' || mix_num || ')' as description,
FROM acid_batch
WHERE mix_num < 10
вы также должны взглянуть на функции
to_char
to_date
to_number
поскольку они дают вам более тонкую детализацию относительно того, как вы хотите, чтобы вещи были представлены.