【问题标题】:SQL replace and calculate character length and replace againSQL替换并计算字符长度并再次替换
【发布时间】:2020-06-11 06:41:28
【问题描述】:

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

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 扩展更新语句?

【问题讨论】:

  • 's:91' 设置在哪里?它是您表中的另一列吗?还是在运行时计算?但是,计算 { 和 } 之间的长度不是问题 - 您可以为此使用 charindex
  • 老实说,您似乎应该对数据进行规范化。
  • 's:91' 设置在同一列参数中。所以它是一种前缀。这是一个火鸟数据库。
  • Firebird 还是 SQL Server ?,因为您已将其标记为 SQL Server,但在评论中说 Firebird
  • 在前端执行,或者在您的应用程序的任何部分执行您存储在"params" 字段中的腌制/冻结/序列化 JSON。你可以强制某些东西工作,但除非你的逻辑理解编码,否则它对所有可能的值永远都不安全。 (例如,如果 SOMEHOST 作为“user”或“pwd”或“path”值的一部分出现怎么办?)这类似于使用 sed 编辑 CSV 文件——它工作得很好,直到它没有。

标签: sql replace firebird


【解决方案1】:

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

使用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:如果在替换主机时还包括标识符会更安全。因此,如果主机名偶然是密码或文件夹的子部分,它们将不会被更改,从而破坏这些值。

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

而不是

替换(参数,'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)) || ':')

【讨论】:

  • Firebirds 尊重 SQL 标准,因此使用 || 进行字符串连接,而不是 +(在 SQL 中添加数字)
  • @a_horse_with_no_name 谢谢,我忘了。我已经更新了答案。
  • @hellskitchen 欢迎您。请阅读我添加的 PS,它会使您的查询更安全。
猜你喜欢
  • 2010-12-09
  • 2020-12-04
  • 1970-01-01
  • 2013-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-16
  • 1970-01-01
相关资源
最近更新 更多