SQL替换并计算字符长度并再次替换

SQL replace and calculate character length and replace again

我想对 Firebird table 进行更新。到目前为止没问题:

update MYTABLE
set params = replace(params, 'SOMEHOST', 'SOMENEWHOST')

在更新语句之前,我的参数如下所示:

s:91:"{"server":"SOMEHOST","port":"21","ssl":false,"user":"DUMMY","pwd":"SECRET","path":"FOLDER"}";

更新后的参数如下所示:

s:91:"{"server":"SOMENEWHOST","port":"21","ssl":false,"user":"DUMMY","pwd":"SECRET","path":"FOLDER"}";

到目前为止没问题。

但是前端程序无法处理这个,因为参数中有校验和。

s:91是左大括号到右大括号的字符长度。

行与行之间的字符长度可能不同,因为存在其他路径、用户或密码。

是否可以计算从左大括号到右大括号的字符长度并使用 Firebird 扩展更新语句?

您首先用新主机替换旧主机,然后进行第二次替换以设置新的尺寸前缀。

使用position函数定位“{”和“}”位置,构建"s:91:"和"s:94:"字符串,替换它们。

update MYTABLE set 
       PARAMS = replace(replace(PARAMS, 'SOMEHOST', 'SOMENEWHOST'), 
                       's:' || cast(position('}' in PARAMS) - position('{' in PARAMS) + 1 as varchar(16)) || ':',
                       's:' || cast(position('}' in replace(PARAMS, 'SOMEHOST', 'SOMENEWHOST')) - position('{' in PARAMS) + 1 as varchar(16)) || ':')

PS:如果在替换 Host 时也包含标识符,会更安全。因此,如果主机名偶然成为密码或文件夹的子部分,它们将不会被更改,从而破坏这些值。

replace(PARAMS, '"server":"SOMEHOST"', '"server":"SOMENEWHOST"')

而不是

replace(PARAMS, 'SOMEHOST', 'SOMENEWHOST')

这使得这个结果查询:

update MYTABLE set 
       PARAMS = replace(replace(PARAMS, '"server":"SOMEHOST"', '"server":"SOMENEWHOST"'), 
                       's:' || cast(position('}' in PARAMS) - position('{' in PARAMS) + 1 as varchar(16)) || ':',
                       's:' || cast(position('}' in replace(PARAMS, '"server":"SOMEHOST"', '"server":"SOMENEWHOST"')) - position('{' in PARAMS) + 1 as varchar(16)) || ':')