Question

Existe-t-il un équivalent ou une alternative à ce qui suit?

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

Oracle propose-t-il un format de style printf?

SELECT printf("%s (%s)", mix_type, mix_num) as description,
  FROM acid_batch
 WHERE mix_num < 10
Était-ce utile?

La solution

Non, aucune fonction Oracle intégrée ne permet d'appliquer une chaîne de mise en forme de cette manière. Bien qu'il soit facile d'écrire une fonction personnalisée pour cet exemple spécifique, écrire une implémentation de printf basée sur PL / SQL serait un défi.

Si vous en avez souvent besoin, vous pourriez peut-être écrire une fonction Oracle qui encapsule un appel Java pour un environnement de traitement de chaîne plus riche.

Autres conseils

L’approximation standard la plus proche de printf pour Oracle que je connaisse est utl_lms.format_message . Cependant, cela ne fonctionnera pas dans les instructions SQL, c’est-à-dire que c’est ok:

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

mais cela donne une erreur ORA-00902: type de données non valide :

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

Juste une autre idée pour vous: j'ai trouvé REPLACE utile pour ce genre de choses, surtout lorsque le modèle est complexe:

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

Le seul inconvénient est que vous devez ajouter autant de REPLACE( qu'il y a de variables à remplacer - mais au moins vous ne devez en avoir qu'une par variable, quel que soit le nombre de fois où elle apparaît dans le modèle.

(REMARQUE: l'utilisation de & ";% &" comme séparateur n'a pas de signification particulière. Il s'agit simplement d'une convention personnelle: vous pouvez choisir un modèle différent, par exemple <mix_type> ou [mix_type])

Dans ce cas particulier, cela ressemble à un excès, mais dans certains cas, cela peut rendre les choses beaucoup plus faciles, par exemple:

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

Comparez ce qui précède avec:

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

J'ai créé un moteur de modèle simple nommé ora_te (sur GitHub) pour Oracle SQL / PLSQL. . Avec votre aide, votre objectif peut être atteint des manières suivantes:

Implémentation non effective avec plusieurs analyses du modèle:

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;

Une implémentation efficace avec une compilation ponctuelle (analyse):

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;

BTW prend également en charge les espaces réservés nommés.

Vous pouvez le résoudre dans la sélection.

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

vous devriez également jeter un coup d'œil aux fonctions

to_char

à la date du jour

nombre_

car ils vous donnent une plus grande précision sur la manière dont vous voulez que les choses soient représentées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top