考虑存储过程,其作业是根据其StatusID或某些其他FK查找表或值范围来检查/更新记录的值.
考虑一个状态表,其中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脚本或存储过程中避免使用魔术数字或硬编码值的其他策略是什么?
关于如何实现这一点的其他一些想法:
>添加一个新的位列(命名为“IsAcknowledged”)和一组规则,其中只能有一行的值为1.这将有助于查找唯一的行:SELECT ID FROM [Status] WHERE [IsAcknowledged] = 1)
解决方法
>使代码更易于阅读(即说“确认”而不是3可能会使您的意图对读者更为明显.
>使代码更加动态,一个函数可以使用参数,而不是几个函数(这不是一个简化,但是这个意思应该是相当不言而喻的)
为各州制定一列可能是一个好的或坏的主意;它真的只取决于数据.如果数据经历了各种“阶段”(收到,确认,审核,拒绝,接受,回复等),那么这种方法可以快速地将自身摆脱生存能力(更不用说必须确保只有一个列在任何给定的时间被设置为1).另一方面,如果状态真的像您所描述的那样简单,那么这样做可以使代码更易读,索引性能更好.
硬编码值中最大的no-no是引用其他实体的硬编码值(换句话说,硬编码相应对象的主键).字符串“已确认”仍然是一个硬编码的值,它的意义更为透明,而不是对其他内容的引用.对我来说,它归结为:如果你能(合理地)查找它,做它.如果你不能(或者某些东西使它成为一个不合理的任务,从性能或可维护性的角度),硬编码.使用这个,你可以通过使用Acknowledged来查找3的值;你不能抬头从其他的东西确认.