问题在于该列中包含很多文本,我只想在特定的文本范围内进行此更改。
在每个示例中,该列均填充有以下数据:
...
<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 <'。基本上,在这两个部分上:
<Value>L44704428/253938478/C01/NOUPLOAD/NOUPLOAD/1/MTPR/MTPR</Value>
<Value>L44704428/253938478/90099326/311/NOUPLOAD/10/MTPR/MTPR</Value>
在ORACLE中有没有办法做到这一点? 预先谢谢你。
最好的问候, 爱德华多
答案 0 :(得分:0)
这是一个非常复杂的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