是否有以下的等效或替代?
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
答案 0 :(得分:20)
我可以想到的最接近于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 :(得分:7)
没有没有以这种方式应用格式化字符串的内置Oracle函数。虽然为这个特定的例子编写一个自定义函数会很容易,但编写一个基于PL / SQL的printf实现将是一项挑战。
如果您经常需要这样做,也许您可以编写一个Oracle函数来包装Java调用以获得更丰富的字符串处理环境。
答案 2 :(得分:3)
另一个想法:我发现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;
答案 3 :(得分:2)
我为Oracle SQL / PLSQL创建了一个名为ora_te (on 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;
BTW它还支持命名占位符。
答案 4 :(得分:1)