我正在处理各种具有WHERE子句的proc,如下所示:
WHERE ... AND ( ( myTbl.myValue = 1234)
or (myTbl.myValue = 1235) )-- Value = No
我和一些同事谈过这个问题,这种代码似乎是不可避免的。我认为将这种代码放入一个(也是唯一一个)的地方是个好主意。这可能是一个视图,它可能是一个表等。我在想一个从底层表中选择的视图,并且有一个位字段,表示值1234或1235是0.或者是'N',等等。方式我可以随意添加'否'值,而无需更改任何代码。如果你在连接中使用它,我不会使用UDF,太多的函数调用。
在数据库中处理特殊值有哪些其他选项?观点是一个很好的解决方案吗?有没有办法完全避免这种事情?我想如果这个价值因为某种原因需要改变我不想处理改变数百个触发器。另一方面,额外的连接因此受到性能影响。
更新:如果有人有策略只是为了摆脱那些也很棒的事情。就像我说的那样,与同事讨论这些事情,这些事情在数据库层中有很多业务逻辑的组织中似乎是不可避免的。
PS:我看到了一些神奇的数字问题,但没有特定的数据库。
答案 0 :(得分:3)
在Oracle上,您可以设置deterministic functions这类函数,注意只需要调用一次的RDBMS。
create or replace package MAGIC is
function magic_number return number DETERMINISTIC;
end;
/
create or replace package body MAGIC is
function magic_number return number DETERMINISTIC
is
begin
return 123;
end;
end;
/
SELECT MAGIC_DATE
FROM MAGIC_TABLE
WHERE MAGIC_ID = magic.magic_number;
答案 1 :(得分:3)
我们谈论了多少魔法数字?如果它不到几千,把它们放在一张桌子上并加入。如果它们经常在WHERE子句中用作一致的分组(如示例中的1234和1235),请指定一个类别列并使用IN或EXISTS。 (这些都不会是一个有意义的性能影响,只有少量幻数和适当的索引。)
我讨厌硬编码的数值,就像你的例子中那些除了临时SQL语句之外的任何数值。它使维护成为一个真正的PITA。
答案 2 :(得分:1)
魔术数字总是可以避免的,但是避免它们可能并不总是理想的(例如你提到的性能)。在完美的代码中,您将在数据库中拥有另一个表,其中包含您引用的简单标识符(字符串),如myMagicNumber
。
但是我发现最好的解决方案是在程序代码中保留查找(函数/枚举等)(如果你正在使用的话,那就是SP)。确保始终使用该查找来添加或选择数据库中的数据。
答案 3 :(得分:1)
我同意这种神奇的数字都应该放在一个地方。该地方应该取决于您的应用程序周围的文化。如果有一个共同的配置文件或区域,特别是一组级联的配置,这是个好地方。
我想你应该想到的第一部分就是你的数字真是太神奇了。配置敏感吗?这是一个数学常数吗?它是由某些外部标准规范定义的值吗?知道这可能有助于找到幻数的定义。
答案 4 :(得分:1)
通常,像这样的幻数可以存储在数据库中,并在首次启动数据库时加载到静态只读变量中。
答案 5 :(得分:0)
使用SqlServer和其他可能的方言你可以创建返回幻数的函数,这样你的sql就会变成
WHERE ... AND ( ( myTbl.myValue = MagicFunction1()) or (myTbl.myValue = MagicFunction2()) )-- Value = No
或者,您可以创建单个函数,或者可以创建一个幻数的函数/逻辑集并传入参数。
WHERE ... AND ( ( myTbl.myValue = ProductFunction(1)) or (myTbl.myValue = ProductFunction(2)) )-- Value = No
答案 6 :(得分:0)
我发现许多老一代开发人员喜欢在他们的代码中添加注释并提供系统文档来备份它们。我自己也不认真,请注意 - 让人们猜猜这一切意味着什么。
答案 7 :(得分:-1)
当我们以字符串查询时,这通常类似于
"AND myTbl.iTpe = "+AnEnum.THE_TYPE.ordinal()+"..."