题
我有一个来自表格的字符串,例如“无法付款{1},因为您的付款{2}将于 {3} 到期”。我想将 {1} 替换为某个值,将 {2} 替换为某个值,将 {3} 替换为某个值。
是否可以实现三合一替换功能?或者有什么方法可以直接编写查询并获取替换值?我想在 Oracle 存储过程中替换这些字符串,原始字符串来自我的一个表,我只是在该表上进行选择
然后我想将该字符串中的 {1},{2},{3} 值替换为我从另一个表中获得的其他值
解决方案
虽然不是一次调用,但是可以嵌套 replace()
呼叫:
SET mycol = replace( replace(mycol, '{1}', 'myoneval'), '{2}', mytwoval)
其他提示
如果有许多变量需要替换,并且您将它们放在另一个表中,并且变量的数量是可变的,则可以使用递归 CTE 来替换它们。下面是一个例子。在表 fg_rulez 中,您将字符串及其替换内容放入其中。在表 fg_data 中,您有输入字符串。
set define off;
drop table fg_rulez
create table fg_rulez as
select 1 id,'<' symbol, 'less than' text from dual
union all select 2, '>', 'great than' from dual
union all select 3, '$', 'dollars' from dual
union all select 4, '&', 'and' from dual;
drop table fg_data;
create table fg_Data AS(
SELECT 'amount $ must be < 1 & > 2' str FROM dual
union all
SELECT 'John is > Peter & has many $' str FROM dual
union all
SELECT 'Eliana is < mary & do not has many $' str FROM dual
);
WITH q(str, id) as (
SELECT str, 0 id
FROM fg_Data
UNION ALL
SELECT replace(q.str,symbol,text), fg_rulez.id
FROM q
JOIN fg_rulez
ON q.id = fg_rulez.id - 1
)
SELECT str from q where id = (select max(id) from fg_rulez);
所以,单个 replace
.
结果:
amount dollars must be less than 1 and great than 2
John is great than Peter and has many dollars
Eliana is less than mary and do not has many dollars
术语符号而不是变量来自 这个重复的问题。
甲骨文11gR2
如果要替换的值的数量太大或者您需要能够轻松维护它,您还可以拆分字符串,使用字典表,最后聚合结果
在下面的示例中,我假设字符串中的单词用空格分隔,并且字符串中的字数不会大于 100(数据透视表基数)
with Dict as
(select '{1}' String, 'myfirstval' Repl from dual
union all
select '{2}' String, 'mysecondval' Repl from dual
union all
select '{3}' String, 'mythirdval' Repl from dual
union all
select '{Nth}' String, 'myNthval' Repl from dual
)
,MyStrings as
(select 'This is the first example {1} ' Str, 1 strnum from dual
union all
select 'In the Second example all values are shown {1} {2} {3} {Nth} ', 2 from dual
union all
select '{3} Is the value for the third', 3 from dual
union all
select '{Nth} Is the value for the Nth', 4 from dual
)
,pivot as (
Select Rownum Pnum
From dual
Connect By Rownum <= 100
)
,StrtoRow as
(
SELECT rownum rn
,ms.strnum
,REGEXP_SUBSTR (Str,'[^ ]+',1,pv.pnum) TXT
FROM MyStrings ms
,pivot pv
where REGEXP_SUBSTR (Str,'[^ ]+',1,pv.pnum) is not null
)
Select Listagg(NVL(Repl,TXT),' ') within group (order by rn)
from
(
Select sr.TXT, d.Repl, sr.strnum, sr.rn
from StrtoRow sr
,dict d
where sr.TXT = d.String(+)
order by strnum, rn
) group by strnum
让我们只编写与 CTE 相同的示例:
with fg_rulez as (
select 1 id,'<' symbol, 'less than' text from dual
union all select 2, '>', 'greater than' from dual
union all select 3, '$', 'dollars' from dual
union all select 4, '+', 'and' from dual
), fg_Data AS (
SELECT 'amount $ must be < 1 + > 2' str FROM dual
union all
SELECT 'John is > Peter + has many $' str FROM dual
union all
SELECT 'Eliana is < mary + do not has many $' str FROM dual
), q(str, id) as (
SELECT str, 0 id
FROM fg_Data
UNION ALL
SELECT replace(q.str,symbol,text), fg_rulez.id
FROM q
JOIN fg_rulez
ON q.id = fg_rulez.id - 1
)
SELECT str from q where id = (select max(id) from fg_rulez);
如果您在选择内部执行此操作,并且替换值是列,则可以使用字符串连接将其拼凑在一起。
不隶属于 StackOverflow