Oracle 'printf' эквивалент
-
05-07-2019 - |
Вопрос
Есть ли эквивалент или альтернатива следующему?
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
Решение
Нет, нет встроенных функций Oracle, которые применяют строку форматирования таким образом. Хотя было бы легко написать пользовательскую функцию для этого конкретного примера, написание реализации printf на PL / SQL было бы сложной задачей. Р>
Если вам это часто нужно, возможно, вы могли бы написать функцию Oracle, которая оборачивает вызов Java для более богатой среды обработки строк.
Другие советы
Самое близкое стандартное приближение к 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
Еще одна идея для вас: я обнаружил, что 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;
Я создал простой шаблонизатор с именем 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;
Кстати, он также поддерживает именованные заполнители.