0

我正在修改一些在记录更新时管理状态更改的存储过程。

例如,如果我有这两个表

Request(RequestID, StatusID)
Status(StatusID, StatusName)

我正在尝试确定处理调用代码状态的最佳方法。

我使用StatusIDorStatusName吗?

不能保证StatusID在环境(DEV、PRE、PROD 等)之间匹配。

此外,StatusName可以更改,我不想更改代码,因为我需要更改StatusName.

我可以创建一个第二个独特的列,它有点类似于StatusID.

我会确保此列在区域之间匹配,但这似乎也不那么干净,而且有点重复。

任何人都可以提出一种更清洁、更简单的方法吗?

4

5 回答 5

2

将代码与数据匹配的困难只能通过第二列部分解决。当有人添加一个项目时,这是什么意思?如果他们重新使用已知常量,如果您不要求此列是唯一的,这意味着什么?

通常我们会有用户可修改的查找表,但它们必须与许多其他标志相关联,这些标志指示如何解释状态 - “IsTreatedAsExpired”、“IsTreatedAsActive”或其他保存被视为特定状态的表事物。

我认为您确实需要首先弄清楚您希望此表允许的范围。因为如果您有大量代码引用,最好使用与所有安装中的代码同步的自然密钥。处理此问题的一种可能性是对不可移动代码使用负数(身份插入以添加新的不可移动代码),然后让您的序列仅添加正数。但是同样,这并没有解决您的程序如何处理或使用用户输入的扩展的语义。

同样,如果不在这里整理出全部范围,就很难说。

于 2013-02-01T20:42:15.207 回答
1

从您提供的信息来看,StatusID在不同的数据库中可能有不同的值,大概是因为您的密钥是自动生成的,而不是您指定的。如果是这样,那么显然StatusID无论如何都不可能在您的代码中始终如一地使用(没有标准化值)。因此,问题变成“在我的代码中硬编码值是否可以接受/实用/可取StatusName?”

显而易见的答案是肯定的,有什么替代方案?如果您有某种表示“就绪”的状态并且您想在代码中引用它,那么您必须在代码中添加一些明确标识状态的内容。

如果您添加某种类型的第二个键(如 Carlos 建议的那样),您仍然会遇到相同的基本问题,即更改自然键值正在更改状态的标识,因此会更改代码的含义。如果您更改“真正的”自然键 ( READY) 而不更改第二个键 ( RDY),那么您的代码将变得更加混乱且难以维护。

如果您执行更复杂的操作,例如将“常量”或“配置参数”提取到配置文件或表中,或者甚至编写自定义预处理器以在部署时将键值插入脚本中,那么您会增加很多复杂性而收效甚微(除非你有其他充分的理由这样做)。我已经看到使用这种方法,这是一个巨大的、无法维护的混乱。

在实践中,StatusName最有可能发生变化是因为 a) 有人认为另一个名称会“更准确”或“看起来更好”,或者 b) 您发现它不能正确地代表您的要求。如果您被迫花时间在 a) 上,那么只需更改前端或报告中的显示名称,而无需理会数据库和代码。如果 b) 出现,那么根据定义,您当前的数据模型和代码是不准确的,无论如何都必须修改和可能修改。而当 b) 确实发生时,它通常会导致添加新代码,而不是更改现有代码(例如,因为有人定义了一个没有现有代码的新流程步骤)。

如果你愿意改变你的开发和部署实践,还有其他方法来看待这个问题,正如其他人所建议的那样。你能让你的StatusID价值观在任何地方都一样吗?从技术上讲这是可能的,那么组织上不这样做的原因是什么?您能否StatusName通过变更管理和代码审查来降低变更的可能性和影响?您能否改进您的需求流程以更有效地捕获某些信息?

于 2013-02-01T22:50:57.410 回答
1

根据经验,当您有 id、值表(状态、结果、区域等)时,我通常会添加第三个字段,它是记录的助记符值,并且始终使用它,既不使用名称也不使用 id。现在助记符值就像一个业务键(嗯,它是一个业务键),因为它是一个业务值,不依赖于数据库(对于 id)或它的显示方式(描述),例如对于您的状态表,您可能有

StatusID,StatusName,StatusMnemo
1       ,COMPLETED ,COM
2       ,REJETED   ,REJ

等等。

在您的查询中,您始终通过 statusId 加入,但您添加了一个子句以通过 StatusMnemo 加入状态表。这是一个独立于环境并保持不变的值。

同样在插入中,您总是使用 statusid。

于 2013-02-01T21:10:46.257 回答
1

编写一个用户定义的函数,该函数接受状态名称并在您引用状态 ID 时给出状态

select * from resources where statusid = dbo.getStatusId("COMPLETED");

这将确保解析状态 ID 始终发生在您定义的函数中

于 2013-02-01T20:42:41.360 回答
0

如果您有需要特殊处理的 statusID 值,那么它们在不同环境中应该是相同的。
为什么要在 Prod 中引入一个需要特殊处理但尚未通过 Pre 和 Dev 的 statusID?

我经常做的是从 100 开始 iden 并将其用于不需要特殊处理的通用状态。

然后DEV拥有100以下的空间,使用IDENTITY INSERT ON进行特殊处理。

如果从 DEV 部署到 PRE 插入任何低于 100 的记录。

于 2013-02-01T21:32:44.633 回答