admin

SQL:避免硬编码或幻数

sql

问: 在SQL脚本或存储过程中,避免幻数或硬编码值还有哪些其他策略?

考虑一个存储过程,该存储过程的工作是根据其StatusID或某些其他FK查找表或值的范围来检查/更新记录的值。

考虑一个Status表,其中ID最重要,因为它是另一个表的FK:

替代文字

应避免的SQL脚本 如下所示

DECLARE  @ACKNOWLEDGED tinyint

SELECT  @ACKNOWLEDGED = 3   --hardcoded BAD

UPDATE  SomeTable
SET     CurrentStatusID = @ACKNOWLEDGED
WHERE   ID = @SomeID

这里的问题是,这不是可移植的,并且显式依赖于硬编码的值。在将其部署到另一个没有标识插入的环境时,存在细微的缺陷。

还尝试避免SELECT基于文本的描述/名称的状态:

UPDATE  SomeTable
SET     CurrentStatusID = (SELECT ID FROM [Status] WHERE [Name] = 'Acknowledged')
WHERE   ID = @SomeID

问: 在SQL脚本或存储过程中,避免幻数或硬编码值还有哪些其他策略?

关于如何实现此目标的其他一些想法:

  • 添加一个新bit列(名称类似“ IsAcknowledged”)和一组规则,其中只能有一个值为的行1。这将有助于找到唯一的行:SELECT ID FROM [Status] WHERE [IsAcknowledged] = 1)

阅读 248

收藏
2021-05-10

共1个答案

admin

在某种程度上,将会有一些“硬编码”的值。消除它们的想法来自两个方面:

  1. 使代码更具可读性(即说'Acknowledged'而不是说3可能 会使您的意图对读者更加明显。
  2. 使代码更具动态性,其中一个函数可以带参数而不是多个不带参数的函数(显然,这是一种简化,但是无论如何含义都应该是不言而喻的)

使bit列各种状态可以是好还是坏主意;
它实际上仅取决于数据。如果数据经过不同的“阶段”(收稿时承认,在审查,拒绝,接受,回应道,等),那么这种做法迅速扩展自身出活力(更何况有保证的刺激性过程
只有一个 的在任何给定时间将列设置为1)。另一方面,如果状态确实如您所描述的那样简单,则这样做可以使代码更具可读性,并且索引的性能更好。

硬编码值中最大的否定是 引用其他实体的硬编码值
(换句话说,硬编码对应对象的主键)。字符串'Acknowledged‘仍然是一个硬编码的值,它的含义更加透明,并且不是对其他内容的引用。对我来说,可以归结为:
如果可以(合理地)查找它,那就去做吧
。如果不能(或者从性能或可维护性的角度来看,使它成为不合理的任务),请对其进行硬编码。使用它,您可以使用来查找3的值Acknowledged。你不能Acknowledged从其他任何东西抬头。

2021-05-10