2008-09-17 17 views
9

में एकाधिक स्ट्रिंग्स को एक साथ कैसे बदलें, मेरे पास {3} "के कारण आपके भुगतान {2} के रूप में" कोई भुगतान नहीं कर सकता {1} जैसी तालिका से आने वाली स्ट्रिंग है। मैं {1} को कुछ मूल्य के साथ प्रतिस्थापित करना चाहता हूं, {2} कुछ मूल्य के साथ और {3} कुछ मूल्य के साथ।ओरेकल

क्या यह एक ही प्रतिस्थापन फ़ंक्शन में सभी 3 को प्रतिस्थापित करना संभव है? या क्या कोई तरीका है कि मैं सीधे प्रश्न लिख सकता हूं और मूल्य बदल सकता हूं? मैं ओरेकल संग्रहीत प्रक्रिया में इन स्ट्रिंग्स को प्रतिस्थापित करना चाहता हूं, मूल स्ट्रिंग मेरी तालिका में से एक से आ रही है, मैं बस उस तालिका पर चयन कर रहा हूं

और फिर मैं {1}, {2}, {3} मानों को प्रतिस्थापित करना चाहता हूं अन्य मूल्य मैं एक मेज

+0

की संभावित डुप्लिकेट [से भी बड़ा एकाधिक की जगह नहीं होगी ओरेकल में फ़ंक्शन] (https://stackoverflow.com/questions/2947623/multiple-replace-function-in-oracle) – Joaquinglezsantos

उत्तर

12

से है कि करने के लिए कि स्ट्रिंग से हालांकि यह एक कॉल नहीं है, आप कर सकते हैं घोंसला replace() कॉल:

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

क्या दूसरा mytwoval गायब एकल उद्धरण है? –

+0

@ सिमोनथीट आप सही हैं! (जब तक Mytwoval एक चर नहीं था) – hamishmcn

-1

आप एक का चयन के इस के अंदर कर रहे हैं, आप कर सकते हैं स्ट्रिंग concatenation का उपयोग कर, अगर आपके प्रतिस्थापन मूल्य कॉलम हैं, तो बस इसे एक साथ टुकड़ा करें।

4

यदि प्रतिस्थापित करने के लिए कई चर हैं और आपके पास उन्हें एक और तालिका में है और यदि चर की संख्या परिवर्तनीय है तो आप उन्हें बदलने के लिए रिकर्सिव सीटीई का उपयोग कर सकते हैं। नीचे एक उदाहरण। तालिका 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 

चर के बजाय शब्दावली प्रतीक this duplicated question. से आता है

ओरेकल 11gR2

+0

ओरेकल 11 जीआर 2 के बाद से खंड में एलिसिंग समर्थित है। – Stephan

+1

आईएमएच यह एक उत्कृष्ट उत्तर है क्योंकि यह उस बिंदु को संबोधित करता है जो दुर्भाग्य से केवल प्रश्न में संदर्भित किया गया था, अर्थात् प्रतिस्थापित शब्दों को वास्तविक क्वेरी को संपादित किए बिना अद्यतन किया जा सकता है (जो एक नियंत्रित वातावरण में उपयोगी परिदृश्य है)। – Neil

1

मूल्यों को बदलने के लिए की संख्या बहुत बड़ी है या आप में सक्षम होना चाहिए आसानी से इसे बनाए रखने के लिए, आप स्ट्रिंग को विभाजित भी कर सकते हैं, एक शब्दकोश तालिका का उपयोग कर सकते हैं और आखिरकार परिणाम

उदाहरण में नीचे मैं यह सोचते हैं रहा है कि अपने स्ट्रिंग में शब्दों blankspaces साथ अलग होती है और स्ट्रिंग में wordcount 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 
+0

एसक्यूएल-केवल समाधान को लागू करने के लिए यह खंड और कुडोज का एक बड़ा उपयोग है, लेकिन परिणाम अभी भी बहुत कठिन है (हम में से कुछ के लिए) पार्स करने के लिए! ऐसा लगता है कि यह अच्छी तरह से काम करता है, लेकिन अगर मैंने अपने कोड में लागू किया है, तो मैं एक सहकर्मी से इसकी शुद्धता के लिए समीक्षा करने के लिए नहीं कहूंगा। वे मुझे गोली मार देंगे! :-) – StewS2