Oracle 'printf'に相当
-
05-07-2019 - |
質問
次のものと同等または代替物はありますか?
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関数はありません。この特定の例のカスタム関数を書くのは簡単ですが、printfのPL / SQLベースの実装を書くのは難しいでしょう。
これが頻繁に必要な場合は、より豊富な文字列処理環境の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
もう1つのアイデア: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(
を追加する必要があることですが、テンプレートに表示される回数に関係なく、少なくとも変数ごとに1つあれば十分です。
(注:<!> quot;%<!> quot;を区切り文字として使用することに特別な意味はありません。これは私の個人的な慣習です。たとえば、<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;
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;
1回のコンパイル(解析)による効果的な実装:
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;
ところで、名前付きプレースホルダーもサポートしています。