【问题标题】:Preventing decimals from entering into a column - Oracle防止小数进入列 - Oracle
【发布时间】:2017-08-21 08:28:29
【问题描述】:

我想知道如果数字的值不是整数,是否有办法防止数字类型的数据进入表格。

即。如果数据包含分数或小数,我不想存储数据。我正在使用 oracle 11g。尽管将比例定义为 0,oracle 仍会将数字的小数部分四舍五入为最接近的整数。

很确定我们必须对列进行某种检查约束,但不太确定那会是什么。

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 有可以使用的整数类型吗?
  • 是的,我确实尝试过。对于 Integer 类型,Oracle 似乎也将值四舍五入到最接近的整数。

标签: sql oracle oracle11g


【解决方案1】:

对于较小的分数,也许使用浮点数?

(因为将比例添加到数字仅适用于定义的范围)

drop table whole_numbers;
create table whole_numbers(a float);
alter table whole_numbers add constraint check_whole check (a = trunc(a));

insert into whole_numbers values(1);

1 row inserted.

insert into whole_numbers values(1.00002);

ORA-02290: check constraint (VBSMASTER.CHECK_WHOLE) violated
*Cause:    The values being inserted do not satisfy the named check

*Action:   do not insert values that violate the constraint.

【讨论】:

  • 感谢您指出这一点。我一直将类型设置为 NUMBER(2,0)。
  • 它适用于大多数情况,但它仍然允许超出比例并接近上限整数或下限整数值的值。对于比例 2,如果我们给出 12.9999 或 10.0001,它会接受这些值而不会出错。有什么解决办法吗?
  • 我最初尝试过这种方式,但我自己有点困惑。它只是自动截断以适应,检查是无用的。现在我看到你发现小分数的问题。如果有必要,你可以有一个检查这个和 raise_application_error 的触发器,但必须有一个更优雅的解决方案。
  • 换句话说,它使用CAST ( 12.9999 as NUMBER(5,2) )之类的东西将输入值转换为列类型,甚至在它到达检查约束之前。
【解决方案2】:

您可以使用check 约束:

alter table t add constraint chk_col_int as (col = trunc(col));

但是,将列声明为整数或不带小数位的数字可能更有意义。嗯,这可能不是你想要的,因为输入的实数/浮点数会被转换而不是产生错误。

【讨论】:

  • 正是我的观点。它被存储为整数而不是引发错误。
  • 上述检查约束似乎没有多大帮助。它仍然存储数字的整数部分。
  • alter table t add constraint chk_col_int as (ceil(col) = floor(col)) enable;怎么样
  • @Gordon Linoff:成功了。但是,就像 Scott 提到的那样,它仅在我将列类型从 NUMBER(2,0) 修改为 NUMBER(3,1) 之后才起作用。也许我应该包括精度和规模。
  • @kfinity 好吧,我说得很快。这两个答案几乎都成功了。但是当输入的数字超过定义的比例并且接近上限整数或下限整数时,它未能引发错误并开始存储。假设您将 NUMBER(3,2) 的比例定义为 2,并尝试输入 1.99999 或 1.00002。这些值存储为 2 或 1。这种行为很奇怪,因为 ceil 和 floor 值对于任何给定的十进制值都不会相等。我可能明白为什么 1.000002 可以被存储,但 1.99999 胜过我。
猜你喜欢
  • 1970-01-01
  • 2016-12-18
  • 1970-01-01
  • 2016-04-11
  • 2020-09-08
  • 2022-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多