Я хочу заменить символ (/) другим символом (¿) внутри определенного текстового диапазона столбца (Oracle SQL) - PullRequest
0 голосов
/ 18 марта 2019

Проблема в том, что в столбце много текста, и я просто хочу сделать это изменение в определенном текстовом диапазоне.

Например, столбец заполнен этими данными:

...

<PropertyBagV2>
            <Item Name="Inventory_Document">
                <ValueList>
                    <Value />
                </ValueList>
            </Item>
            <Item Name="SupplierPartnerNo">
                <ValueList>
                    <Value />
                </ValueList>
            </Item>
            <Item Name="LabelNumber">
                <ValueList>
                    <Value>253938478/L44704428</Value>
                </ValueList>
            </Item>
            <Item Name="PalletProductList">
                <ValueList>
                    <Value>L44704428/253938478/C01/NOUPLOAD/NOUPLOAD/1/MTPR/MTPR</Value>
                    <Value>L44704428/253938478/90099326/311/NOUPLOAD/10/MTPR/MTPR</Value>
                </ValueList>
            </Item>
        </PropertyBagV2>
    </SessionContext>

...

Но я хочу заменить '/' на '¿' только из сегмента 'L%' в '/ MTPR <'.В основном, на этих 2 частях: </p>

<Value>L44704428/253938478/C01/NOUPLOAD/NOUPLOAD/1/MTPR/MTPR</Value>                 
<Value>L44704428/253938478/90099326/311/NOUPLOAD/10/MTPR/MTPR</Value>

Есть ли способ сделать это в ORACLE?Заранее спасибо.

С уважением, Эдуардо

1 Ответ

0 голосов
/ 19 марта 2019

Вот очень запутанный оператор SQL, который делает то, что вы хотите. Я не мог понять, как ограничить regexp_replace строкой со списком значений, поэтому я разделил текст на несколько строк, сделал замену, а затем рекомбинировал ее.

WITH
-- Original value to be replaced
aset AS( SELECT q'[<PropertyBagV2>
        <Item Name="Inventory_Document">
            <ValueList>
                <Value />
            </ValueList>
        </Item>
        <Item Name="SupplierPartnerNo">
            <ValueList>
                <Value />
            </ValueList>
        </Item>
        <Item Name="LabelNumber">
            <ValueList>
                <Value>253938478/L44704428</Value>
            </ValueList>
        </Item>
        <Item Name="PalletProductList">
            <ValueList>
                <Value>L44704428/253938478/C01/NOUPLOAD/NOUPLOAD/1/MTPR/MTPR</Value>
                <Value>L44704428/253938478/90099326/311/NOUPLOAD/10/MTPR/MTPR</Value>
            </ValueList>
        </Item>
    </PropertyBagV2>
</SessionContext>]' AS t, CHR( 10 ) AS lf FROM DUAL ),
-- Split the record into multiple records using the trailing line feed as the separator
    splitit ( t
            , REMAINDER
            , lf
            , r ) AS
        (                         -- Ensure the last line is included by adding a trailing line feed
         SELECT SUBSTR( t || lf, 1, INSTR( t || lf, lf ) - 1 )     AS t
              , SUBSTR( t || lf, INSTR( t, lf ) + 1 )              AS REMAINDER
              , lf
              , 1                                                  AS r
           FROM aset
         UNION ALL
         SELECT SUBSTR( REMAINDER, 1, INSTR( REMAINDER, lf ) - 1 )     AS t
              , SUBSTR( REMAINDER, INSTR( REMAINDER, lf ) + 1 )        AS REMAINDER
              , lf
              , r + 1                                                  AS r
           FROM splitit
          WHERE REMAINDER IS NOT NULL AND t IS NOT NULL),
    repl AS
        (SELECT t
              ,                
              -- Only replace slashes on records starting with spaces and <value>L
              -- 'i' makes the match case insensitive
                CASE
                    WHEN REGEXP_LIKE( t, '^ *<value>L.*</value>$', 'i' )
                    THEN
                        -- I am using ' boo ' instead of odd character questioner
                        -- requested. Substitute your own string for ' boo '
                        REPLACE( t, '/', ' boo ' )
                    ELSE
                        -- no match, just return original string
                        t
                END    replaced
              , r
           FROM splitit)
-- LISTAGG will recombine the multiple records back into a single record
SELECT LISTAGG( replaced, CHR( 10 ) ) WITHIN GROUP (ORDER BY r)     AS t
  FROM repl
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...