使用 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;

SQLFiddle here

您可以使用正则表达式:

UPDATE sumcon
SET    datos   = REGEXP_REPLACE( datos, '(/(.*?/){7}).*?/', '' || :new_value || '/' )
WHERE  nis_rad = 200000732;
  • (/(.*?/){7}) - 将找到第一个 / 然后将匹配零个或多个任何字符 .*? 直到找到另一个 / 然后重复此匹配7 次(获得第一个斜线,然后是 7 个连续的斜线)- 这将全部存储在一个捕获组中(由周围的 ()s 表示)。
  • .*?/ 将匹配零个或多个字符 .*? 直到找到另一个 / - 这就是您要替换的内容。