问题: Oracle如何使用PLSQL进行字符串插值?给定一个包含在大括号内的命名参数的模板,然后用命名参数替换变量。功能类似于C# 字符串插值、Java 等语言。代码应该针对性能进行优化,尽管大多数代码不会经常使用。
大括号是强制性的,因为模板是业务用户定义并保存在表中的。这是公司使用的标准惯例。目标是在 Oracle 本身中“邮件合并”业务文档和片段。
实现:
最好封装在 PLSQL 和 SQL 中运行的函数。对于 SQL,名称值对的 csv 列表将在 example 中传递'name, jane, age, 26'。name, value, name, valueETC...
示例用例:
请注意使用双大括号作为文字“{”的转义符。模板将存储在数据库表中,替换变量将在运行时根据复杂的规则导出。下面的例子很简单:
模板='Hi my name is {name}, I am aged {age}, yes {age}! Replaced placeholders {{name}}, {{age}}'
变量=name: jane, age: 26
输出=Hi my name is Jane, I am aged 26, yes 26! Replaced placeholders {name} and {age}
调用虚构包的 PLSQL 示例:
DECLARE v_template NVARCHAR2(500);
v_name NVARCHAR2(50) := 'Jane';
v_age NVARCHAR2(50) := '26';
v_output NVARCHAR2(1000); TYPE ty_dictionary IS TABLE OF NVARCHAR2(1000) INDEX BY VARCHAR2(200);
v_vars ty_dictionary;
BEGIN
-- note, escaped double curly braces {{ will output {,
v_template := 'Hi my name is {name}, I am aged {age}, yes {age}! Replaced placeholders {{name}}, {{age}}';
v_vars('name') := v_name;
v_vars('age') := v_age;
v_output:= pkg_interpolation.fn_format(v_template, v_vars);
-- should output:
-- Hi my name is Jane, I am aged 26, yes 26! Replaced placeholders {name} and {age}
dbms_output.put_line('output: ' || v_output);
END;
Run Code Online (Sandbox Code Playgroud)
尝试这样的事情(db<>fiddle):
declare
type vararg is table of varchar2 (96) index by varchar2 (32);
function format (template varchar2, args vararg) return varchar2 is
key varchar2 (32);
ret varchar2 (32767) := template;
pattern varchar2 (32) := '(^|[^{]){(\w+)}([^}]|$)';
begin
<<substitute>> loop
key := regexp_substr (ret, pattern, 1, 1, null, 2);
exit substitute when key is null;
ret := regexp_replace (ret, pattern,
'\1'||case when args.exists (key) then args (key) else '?'||key||'?' end||
'\3', 1, 1);
end loop;
return replace (replace (ret, '{{','{'), '}}', '}');
end;
begin
dbms_output.put_line ('output: '||format (q'[
{name} said: Hi my name is {name}, I am aged {age}, yes {age}!
Missing key {somekey}; Replaced placeholders {{name}}, {{age}}. Again I am {age}]',
vararg ('name' => 'Jane',
'age' => '26')));
end;
/
Run Code Online (Sandbox Code Playgroud)
输出:
Jane 说:嗨,我叫 Jane,我今年 26 岁,是的 26 岁!
缺少钥匙?somekey?;替换了占位符 {name}、{age}。我又26岁了