首页 > 解决方案 > 使用同一列的一部分替换表列值

问题描述

我正在更新表中的一列,将一列替换为其现有值的一部分:

Update Table_Name Set VarName '12345' where VarName = 'AA-BB-12345';
Update Table_Name Set VarName '99999' where VarName = 'XX-AR-99999';
...

如何在循环中执行此操作,以便通过整个Table_Name表进行更改,拉出最后一个元素VarName并使用它进行更新?表中有 500 行要更新,单行更新太多,所以我需要一个循环来完成。

我认为这很接近:

Update Table_Name
set VarName = ( select regexp_substr(VarName, '[^-]+,1,3 ) from Table_Name );

标签: sqloracleoracle11gsql-update

解决方案


您离得不远,但您的子查询不相关 - 子查询找到的值与正在更新的行之间没有链接,因此您可能会收到 ORA-01427 错误。但是您不需要子查询,因为您正在更新同一行:

update table_name set varname = regexp_substr(varname, '[^-]+', 1, 3);

您也可以在没有正则表达式的情况下执行此操作:

update table_name set varname = substr(varname, instr(varname, '-', -1) + 1);

这还具有不将任何不是预期模式的行归零的优点。即便如此,您也可以通过仅使用破折号更新值来减少不必要的工作:

update table_name set varname = substr(varname, instr(varname, '-', -1) + 1)
where instr(varname, '-', -1) > 0;

或者

update table_name set varname = regexp_substr(varname, '[^-]+', 1, 3)
where regexp_substr(varname, '[^-]+', 1, 3) is not null;

这只会更新旧值具有(至少)三个元素的行。

如果有两个元素,则这两个更新的行为会有所不同——如果有的话,第一个带有substr/instr破折号的总是会占据最后一部分;第二个rexexp_substr不会用一个破折号更新一个。您只展示了一种固定模式,因此这些都可能与您无关。至少,直到您再次针对该数据运行相同的更新...


推荐阅读