Oracle 'printf' эквивалент - PullRequest
       39

Oracle 'printf' эквивалент

13 голосов
/ 16 июня 2009

Есть ли эквивалент или альтернатива следующему?

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

Ответы [ 5 ]

20 голосов
/ 16 марта 2012

Ближайшее стандартное приближение к 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
7 голосов
/ 17 июня 2009

Нет, нет встроенных функций Oracle, которые применяют строку форматирования таким способом. Хотя было бы легко написать пользовательскую функцию для этого конкретного примера, написание реализации printf на PL / SQL было бы сложной задачей.

Если вам это часто нужно, возможно, вы могли бы написать функцию Oracle, которая оборачивает вызов Java для более богатой среды обработки строк.

3 голосов
/ 17 июня 2009

Еще одна идея для вас: я обнаружил, что 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;
2 голосов
/ 29 апреля 2015

Я сделал простой движок шаблонов с именем 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;

Кстати, он также поддерживает именованные заполнители.

1 голос
/ 17 июня 2009

Вы можете разрешить его в выборе.

SELECT mix_type || '(' ||  mix_num || ')' as description,
FROM acid_batch
WHERE mix_num < 10

Вы также должны взглянуть на функции

to_char

to_date

to_number

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

...