【问题标题】:Setting column constraint on a table (SQL Server)在表上设置列约束 (SQL Server)
【发布时间】:2010-08-11 18:58:02
【问题描述】:

我有一列应该包含 2 power n: 2,4,8,16,32 等值之一。我想在表架构级别强制执行 - 有没有办法指定这样的列约束?

谢谢!

【问题讨论】:

  • 你能说出你这样做的原因吗?
  • 好吧,我突然想到我应该存储 n 而不是 2 power n :) 案例解决了!

标签: sql sql-server constraints


【解决方案1】:

无耻地从 this answer 窃取你可以使用按位运算来非常有效地做到这一点。

ALTER TABLE tablename ADD CONSTRAINT
    ckname CHECK (colName > 0 AND (colName & (colName - 1) =0))

【讨论】:

    【解决方案2】:

    在 SQL Server 中:

    ALTER TABLE [dbo].[PowerOfTwo]
    WITH CHECK ADD  CONSTRAINT [CK_PowerOfTwo] 
    CHECK  ((log([Value])/log(2)=round(log([Value])/log(2), 0, 1)))
    

    【讨论】:

      【解决方案3】:

      如何将列定义为 N。那么根据定义,该列的所有用途将是 2^n,而不是约束。

      否则 - 您可以放置​​触发逻辑以在输入或更新每个值时对其进行验证。

      【讨论】:

      • 几分钟前我已经想通了 :) 无论如何我都会支持你,因为这是个好主意
      【解决方案4】:

      假设您的列名是 N。尝试类似

      CHECK(LOG(N)/LOG(2) = TRUNC(LOG(N)/LOG(2)))
      

      目的是验证值 N 的二进制对数是否为整数,这意味着 N 是 2 的幂。不确定 SQL Server 是否支持 LOG 和 TRUNC 函数 - 根据需要替换为正确的名称.

      编辑:当我重读这篇文章时,我意识到四舍五入可能会导致问题(我忘记了浮点的第二条诫命,即:你永远不要比较浮点值是否相等!)。好的,怎么样

      CHECK(ABS(LOG(N)/LOG(2) - TRUNC(LOG(N)/LOG(2))) < 0.00001)
      

      或用任何你想要的容错替换 0.00001。

      分享和享受。

      【讨论】:

        【解决方案5】:

        创建列检查:

        CHECK (column_name IN (2, 4, 8, 16, 32, ..., 2147483648))
        

        【讨论】:

        • 投反对票的原因是什么?
        • 是的,我是认真的。这个答案在概念上与公认的答案有何不同?是的,我认为使用简单的值列表会更好,因为很少,而不是调用log 4 次,但除了那个(不相关的)差异之外,没有别的了。或者您是否暗示您的专栏实际上是 double 类型,而不是 int ?在这种情况下,接受的答案也是错误的,因为浮点精度有限,因此比较可能不如您预期的那样真实。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-07-17
        • 2011-04-19
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多