Подтвердить что ты не робот

Эквивалент 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
4b9b3361

Ответ 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

поскольку они дают вам более тонкую детализацию относительно того, как вы хотите, чтобы вещи были представлены.