【问题标题】:How to replace text based on another table?如何根据另一个表格替换文本?
【发布时间】:2017-08-24 23:54:57
【问题描述】:

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

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  | ...

有人可以帮忙吗?

【问题讨论】:

  • @MT0,如果你能帮忙解决这个问题,我会很高兴 :)
  • 为什么不直接删除每个方括号?
  • 我们对您的问题一无所知。你到底想达到什么目的?这两个表应该如何交互?你试过什么?
  • REPLACE(REPLACE(col, '[', ''),']',''), 先替换左括号,再获取新字符串,替换右括号。
  • 我的问题:这些只是为了好玩还是我们真正需要这样的数据操作?

标签: sql oracle


【解决方案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;

【讨论】:

  • 谢谢!用你的例子我可以完成这个任务,玩得开心;)
  • 我不明白一件事。 p.index 是什么意思?也许是 p.rownum?
【解决方案2】:

你可以像这样写一个 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;

【讨论】:

  • 不,plsql被拒绝:(只有核心,只有原生sql。
【解决方案3】:

假设括号的数量并不总是相同,您可以使用类似的方法。这是一个功能示例:

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

【讨论】:

  • 这似乎是一个 SQL Server 的答案 - 不幸的是,这个问题被标记为 Oracle,这不会回答这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 1970-01-01
相关资源
最近更新 更多