كيفية استبدال سلاسل متعددة معًا في أوراكل

StackOverflow https://stackoverflow.com/questions/83856

  •  01-07-2019
  •  | 
  •  

سؤال

لدي سلسلة قادمة من جدول مثل "لا أستطيع الدفع{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);

إذا كنت تفعل ذلك داخل التحديد، فيمكنك فقط تجميعه معًا، إذا كانت قيم الاستبدال الخاصة بك عبارة عن أعمدة، باستخدام تسلسل السلسلة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top