Pregunta

¿Existe un equivalente o una alternativa a lo siguiente?

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

¿Oracle tiene algo así como el formato de estilo printf?

SELECT printf("%s (%s)", mix_type, mix_num) as description,
  FROM acid_batch
 WHERE mix_num < 10
¿Fue útil?

Solución

No, no hay funciones integradas de Oracle que apliquen una cadena de formato de esta manera. Aunque sería fácil escribir una función personalizada para este ejemplo específico, escribir una implementación de printf basada en PL / SQL sería un desafío.

Si tiene una necesidad frecuente de esto, tal vez podría escribir una función de Oracle que envuelva una llamada de Java para un entorno de manejo de cadenas más rico.

Otros consejos

La aproximación estándar más cercana a printf para Oracle que se me ocurre es utl_lms.format_message . Sin embargo, no funcionará en sentencias SQL, es decir, está bien:

begin
  dbms_output.put_line(
    utl_lms.format_message('hello %s, the number is %d', 'world', 42)
  );
end;
/

pero esto da un ORA-00902: error de tipo de datos no válido :

select utl_lms.format_message('hello %s, the number is %d', 'world', 42)
  from dual

Solo otra idea para ti: he encontrado que REPLACE es útil para este tipo de cosas, especialmente cuando la plantilla es compleja:

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

El único inconveniente es que necesita agregar tantos REPLACE( como haya variables para reemplazar, pero al menos solo necesita tener uno por variable, independientemente de cuántas veces aparezca en la plantilla.

(NOTA: No hay una importancia particular para usar "% " como delimitador, es solo una convención personal mía; puede elegir un patrón diferente, por ejemplo, <mix_type> o [mix_type])

Para esta instancia en particular, parece excesivo, pero en algunos casos puede hacer las cosas mucho más fáciles, por ejemplo:

template := 'bla bla %a% %b% %a%';
output := REPLACE(REPLACE(template
    ,'%a%', some_complex_expression)
    ,'%b%', b);

Compare lo anterior con:

output := 'bla bla ' || some_complex_expression || ' ' || b || ' ' || some_complex_expression;

He creado un motor de plantillas simple llamado ora_te (en GitHub) para Oracle SQL / PLSQL . Con la ayuda de este, su objetivo se puede lograr de las siguientes maneras:

Implementación no efectiva con múltiples análisis de cadena de plantilla:

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;

Una implementación efectiva con una compilación única (análisis):

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;

Por cierto, también admite marcadores de posición con nombre.

Puede resolverlo en la selección.

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

también deberías echar un vistazo a las funciones

to_char

to_date

to_number

ya que le dan una granularidad más fina sobre cómo quiere que se representen las cosas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top