oracle - se8 - printstream out



Oracleの 'printf'と同等のもの (4)

以下と同等または代替的なものはありますか?

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 SQL / PLSQL用にora_te(GitHub上)という単純なテンプレートエンジンを作成しました。 それの助けを借りてあなたの目標は次のようにして達成することができます。

テンプレート文字列の複数の解析を伴う無効な実装

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;

ところでそれはまた名前付きプレースホルダーをサポートしています。


あなたにとってもう一つのアイデア:私は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(する変数と同じ数のREPLACE(を追加する必要があることです。ただし、テンプレートに表示される回数に関係なく、少なくとも変数ごとに1つだけ必要です。

(注:区切り文字として "%"を使用することに特別な意味はありません。それは私の個人的な慣習です - あなたは別のパターンを選択するかもしれません、例えば<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;

いいえこの方法でフォーマット文字列を適用する組み込みのOracle関数はありません。 この特定の例のカスタム関数を書くのは簡単ですが、PL / SQLベースのprintf実装を書くのは難しいでしょう。

これが頻繁に必要になる場合は、おそらく、より豊富な文字列処理環境に対するJava呼び出しをラップするOracle関数を書くことができます。


私が考えることができるOracleのprintfに最も近い標準的な近似は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




printf