使用 substr 和 instr 更新分隔字符串
Using substr and instr to update a delimited string
我在名为 datos
的列中有以下数据。我想更新第 8 个斜杠 (DR004) 之后的文本,使其成为 DR013。
/1/14/0/0/ / / /DR004/1/rttrgftgr/ZM003/0/0/0/1/0/
我试过用这个
update sumcon
set substr(datos, instr(datos, '/', 1, 8) + 1, 1) =
decode(substr(datos, instr(datos, '/', 1, 8) + 1, 1), ' ', 'DR013')
where nis_rad = 200000732;
但它不起作用。
这是来自 datos
列的数据示例
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / /DR008/1/ /ZM004/0/0/0/0/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/1/0/0/0/
/1/14/0/0/ / / /DR008/1/ /ZM004/0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/1/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / /DR001/1/ /ZM004/0/0/0/0/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
如果它有效,我会感到惊讶。
您可以执行类似于
的操作
update sumcon
set datos = substr(datos, 1, instr(datos, '/', 1, 7) ||
:new_value ||
substr(datos, instr(datos, '/', 1, 8)
where nis_rad = 200000732;
但通常你不应该那样做。相反,您应该重新设计 table 并将 datos
字段划分为多个原子字段。
根据 @LalitKumarB's 建议,将您的 UPDATE 语句更改为
UPDATE SUMCON
SET DATOS = SUBSTR(DATOS, 1, INSTR(DATOS, '/', 1, 8)) ||
'DR013' ||
SUBSTR(DATOS, INSTR(DATOS, '/', 1, 9))
WHERE NIS_RAD = 200000732;
您可以使用正则表达式:
UPDATE sumcon
SET datos = REGEXP_REPLACE( datos, '(/(.*?/){7}).*?/', '' || :new_value || '/' )
WHERE nis_rad = 200000732;
(/(.*?/){7})
- 将找到第一个 /
然后将匹配零个或多个任何字符 .*?
直到找到另一个 /
然后重复此匹配7 次(获得第一个斜线,然后是 7 个连续的斜线)- 这将全部存储在一个捕获组中(由周围的 ()
s 表示)。
.*?/
将匹配零个或多个字符 .*?
直到找到另一个 /
- 这就是您要替换的内容。
我在名为 datos
的列中有以下数据。我想更新第 8 个斜杠 (DR004) 之后的文本,使其成为 DR013。
/1/14/0/0/ / / /DR004/1/rttrgftgr/ZM003/0/0/0/1/0/
我试过用这个
update sumcon
set substr(datos, instr(datos, '/', 1, 8) + 1, 1) =
decode(substr(datos, instr(datos, '/', 1, 8) + 1, 1), ' ', 'DR013')
where nis_rad = 200000732;
但它不起作用。
这是来自 datos
列的数据示例
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / /DR008/1/ /ZM004/0/0/0/0/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/1/0/0/0/
/1/14/0/0/ / / /DR008/1/ /ZM004/0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/1/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
/1/14/0/0/ / / /DR001/1/ /ZM004/0/0/0/0/0/
/1/14/0/0/ / / / /1/ / /0/0/0/1/0/
如果它有效,我会感到惊讶。
您可以执行类似于
的操作update sumcon
set datos = substr(datos, 1, instr(datos, '/', 1, 7) ||
:new_value ||
substr(datos, instr(datos, '/', 1, 8)
where nis_rad = 200000732;
但通常你不应该那样做。相反,您应该重新设计 table 并将 datos
字段划分为多个原子字段。
根据 @LalitKumarB's 建议,将您的 UPDATE 语句更改为
UPDATE SUMCON
SET DATOS = SUBSTR(DATOS, 1, INSTR(DATOS, '/', 1, 8)) ||
'DR013' ||
SUBSTR(DATOS, INSTR(DATOS, '/', 1, 9))
WHERE NIS_RAD = 200000732;
您可以使用正则表达式:
UPDATE sumcon
SET datos = REGEXP_REPLACE( datos, '(/(.*?/){7}).*?/', '' || :new_value || '/' )
WHERE nis_rad = 200000732;
(/(.*?/){7})
- 将找到第一个/
然后将匹配零个或多个任何字符.*?
直到找到另一个/
然后重复此匹配7 次(获得第一个斜线,然后是 7 个连续的斜线)- 这将全部存储在一个捕获组中(由周围的()
s 表示)。.*?/
将匹配零个或多个字符.*?
直到找到另一个/
- 这就是您要替换的内容。