如何根据另一个表替换文本?

时间:2017-08-24 14:58:03

标签: sql oracle

在我的数据库中我有这样的结构

text:
id | text
1  | sample text [[[aaa]]], random text [[[bbb]]] ... [[[zzz]]]]
n  | ...

params:
name | value
aaa  | 111
bbb  | 222
...  | ...
zzz  | 7878778

我不知道每个字符串中有多少[[[]]]]块,所以我不能使用regexp_replace。 选择之后我想得到这个:

text:
    id | text
    1  | sample text 111, random text 222 ... 7878778
    n  | ...

有人可以帮忙吗?

3 个答案:

答案 0 :(得分:1)

这样的事情:

WITH indexed_params ( id, name, value, num_params ) AS (
  SELECT ROWNUM, name, value, COUNT(1) OVER () FROM params
),
replacement ( id, text, idx, num_params ) AS (
  SELECT id,
         REPLACE( text, '[[' || p.name || ']]', p.value ),
         1,
         p.num_params
  FROM   inputs i
         LEFT OUTER JOIN indexed_params p
         ON ( p.index = 1 )
UNION ALL
  SELECT r.id,
         REPLACE( r.text, '[[' || p.name || ']]', p.value ),
         r.idx+1,
         r.num_params
  FROM   replacement r
         INNER JOIN indexed_params p
         ON ( p.index = r.idx+1 )
  WHERE  r.idx < r.num_params
)
SELECT id, text
FROM   replacement
WHERE  idx = num_params;

答案 1 :(得分:0)

您可以编写像这样的PL / SQL函数

function replace_params (p_string varchar2) return varchar2 is
  l_newstr varchar2(32767) := p_string;
begin
  for r in (select name, value from params) loop
    l_newstr := replace (l_newstr, '[[[' || r.name || ']]]', r.value);
  end loop;
  return l_newstr;
end;

然后申请文本:

select replace_params(text) from text;

答案 2 :(得分:-1)

你可以使用这样的东西,假设括号的数量并不总是相同的。这是一个功能性的例子:

create table #Text
(
    _id int, 
    _text nvarchar(500)
) 

Insert Into #Text SELECT 1, 'sample text [[[aaa]]], random text [[[bb]]] ... [[zzz]]'

create table #Params
(
    _name nvarchar(50), 
    _value nvarchar(50)
)

Insert Into #Params SELECT 'aaa', '111'
Insert Into #Params SELECT 'bb', '222'
Insert Into #Params SELECT 'zzz', '999'

Declare @_result nvarchar(500);

Set @_result = (Select _text from #Text WITH (NOLOCK) 
Where _id = 1 )

SELECT @_result;

declare c cursor local for 
Select _name,_value from #Params WITH (NOLOCK)

declare @_name nvarchar(50), @_value nvarchar(50)
open c
FETCH NEXT FROM c INTO @_name, @_value
WHILE @@fetch_status = 0 
    BEGIN
    SET @_result = REPLACE(@_result,'['+@_name+']',@_value);
    FETCH NEXT FROM c INTO @_name, @_value
    END
CLOSE c
DEALLOCATE c

SET @_result = REPLACE(REPLACE(@_result,'[',''),']','');

SELECT @_result;

DROP TABLE #Text
DROP TABLE #Params