2013-07-03 4 views
2

Есть ли какой-нибудь хороший трюк для изменения значений в строке с использованием сопоставления словарей? Например, у меня есть table1FIDDLEOracle 11g: Заменить часть строки с использованием сопоставления словаря

+---------------------------+ 
|   ROW1    | 
+---------------------------+ 
| This is an example string | 
| This String has typ0s  | 
+---------------------------+ 

А некоторые таблицы отображения dict1FIDDLE:

+-------------------------+ 
|  OLD | NEW  | 
+-------------------------+ 
| THIS  | THAT  | 
| IS   | ARE  | 
| EXAMPLE | SOURCE  | 
| STRING  | NUMBER  | 
+------------+------------+ 

мне нужно некоторое SELECT утверждение, что будет разделить значения в table1.row1 и изменять слова, используя Mapping словарю dict1 полученные таким образом значения будут (изменение существующих значений словаря на верхний не является обязательным):

+---------------------------+ 
|  TRANS_ROW1   | 
+---------------------------+ 
| THAT ARE AN SOURCE NUMBER | 
| THAT NUMBER HAS TYP0S  | 
+---------------------------+ 

PS. Разделение с использованием выражения REGEXP будет таким приятным.

+0

вы возражаете PLSQL в функции? – Randy

ответ

1
WITH dict1 AS 
(SELECT 'THIS' fr, 
     'THAT' t 
    FROM dual 
    UNION ALL 
    SELECT 'IS' fr, 
     'ARE' t 
    FROM dual 
    UNION ALL 
    SELECT 'EXAMPLE' fr, 
     'SOURCE' t 
    FROM dual 
    UNION ALL 
    SELECT 'STRING' fr, 
     'NUMBER' t 
    FROM dual), 
table1 AS 
(SELECT 'This is an example string' AS str, 
     1 AS sn 
    FROM dual 
    UNION ALL 
    SELECT 'This String has typ0s' AS str, 
     2 sn 
    FROM dual), 
src AS 
(SELECT regexp_substr(upper(s.str), '[^ ]+', 1, LEVEL) str2, 
     s.*, 
     rownum nn 
    FROM table1 s 
    CONNECT BY instr(TRIM(' ' FROM str), ' ', 1, LEVEL - 1) > 0 
     AND PRIOR sn = sn 
     AND PRIOR dbms_random.value IS NOT NULL), 
repl AS 
(SELECT nvl2(dict1.t, dict1.t, src.str2) lex, 
     sn, 
     nn 
    FROM src 
    LEFT JOIN dict1 
     ON dict1.fr = src.str2) 
SELECT listagg(lex, ' ') within GROUP(ORDER BY nn), 
     sn 
    FROM repl 
GROUP BY sn 

Он работает сейчас, как вы просите. Наслаждаться.

EDIT: FIDDLE раствором

+0

Довольно впечатляет .. но можете ли вы объяснить, почему вы добавляете 'AND PRIOR dbms_random.value IS NOT NULL'? – WBAR

+0

, чтобы избавиться от возможных циклов во время разбора строки. иногда это происходит, когда мы имеем равные значения в одной строке, например, «oo bb oo» –

+0

в соответствии с вашим ответом. Я изменил свою скрипту на http://sqlfiddle.com/#!4/d0a21/10/0 – WBAR

Смежные вопросы