Как заменить несколько строк вместе в Oracle

У меня есть строка из таблицы вроде "не могу заплатить {1}, так как ваш платеж {2} должен быть произведен {3}". Я хочу заменить {1} некоторым значением, {2} некоторым значением и {3} некоторым значением.

Можно ли заменить все 3 в одной функции замены? или есть ли способ напрямую написать запрос и получить замененное значение? Я хочу заменить эти строки в хранимой процедуре Oracle, исходная строка поступает из одной из моих таблиц, я просто выбираю в этой таблице

а затем я хочу заменить значения {1}, {2}, {3} из этой строки на другое значение, которое у меня есть из другой таблицы

Возможный дубликат Множественная функция REPLACE в Oracle

Joaquinglezsantos 06.11.2017 17:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
1
36 549
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Ответ принят как подходящий

Хотя это не один вызов, вы можете вложить вызовы replace():

SET mycol = replace( replace(mycol, '{1}', 'myoneval'), '{2}', mytwoval)

Во втором mytwoval отсутствуют одинарные кавычки?

Simon The Cat 06.10.2014 19:13

@SimonTheCat Вы правы! (Если mytwoval не был переменной)

hamishmcn 09.10.2014 08:55

Если вы делаете это внутри select, вы можете просто собрать его вместе, если ваши замещающие значения являются столбцами, используя конкатенацию строк.

Если есть много переменных, которые нужно заменить, и они есть в другой таблице, и если количество переменных является переменным, вы можете использовать рекурсивный 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

Псевдонимы в предложении WITH поддерживаются начиная с Oracle 11gR2.

Stephan 28.05.2015 15:29

IMH, это отличный ответ, потому что он касается точки, на которую, к сожалению, только косвенно ссылались в вопросе, а именно позволяет обновлять замененные термины без редактирования фактического запроса (что является полезным сценарием в контролируемой среде).

Neil 28.01.2016 17:05

Если количество заменяемых значений слишком велико или вам нужно иметь возможность легко поддерживать его, вы также можете разделить строку, использовать таблицу словаря и, наконец, агрегировать результаты

В приведенном ниже примере я предполагаю, что слова в вашей строке разделены пробелами, а количество слов в строке не будет больше 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

Это отличное использование предложения WITH и похвалы для реализации решения только на SQL, но результат все еще довольно сложен (для некоторых из нас) для анализа! Кажется, это работает хорошо, но если бы я реализовал свой код, я бы не стал просить коллег проверить его на правильность. Они бы меня застрелили! :-)

StewS2 07.03.2018 20:47

Напишем тот же образец только для 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);

Другие вопросы по теме