我试图在oracle中找到一种方法来限制数字(10)数据类型的最大值为2,147,483,647。根据oracle网站,下面是数字(10)的详细范围。但我可以看到我们可以添加值> 2,147,483,647直到它是十位数。有没有办法(除了添加约束)限制价值?
NUMBER(10)
有符号长整数。
大小:4个字节
范围:-2147483648至+2147483647
答案 0 :(得分:13)
(说真的,只需使用此解决方案)
CREATE TABLE x (i NUMBER(10) CHECK (i BETWEEN -2147483648 AND 2147483647));
CREATE TABLE x (i NUMBER(10));
CREATE TRIGGER x_int_trg
BEFORE INSERT OR UPDATE
ON x
REFERENCING NEW AS new
FOR EACH ROW
BEGIN
IF :new.i NOT BETWEEN -2147483648 AND 2147483647 THEN
raise_application_error(-20000, 'Not a 32 bit integer');
END IF;
END x_int_trg;
/
使用带有WITH CHECK OPTION
子句的视图,并始终通过该视图插入/更新数据。通过设置适当的授权来防止直接访问表。 (当然,我仍然会添加约束,但你不想这样做。)
CREATE TABLE x_hidden_implementation (i NUMBER(10));
CREATE OR REPLACE VIEW x AS
SELECT * FROM x_hidden_implementation
WHERE i BETWEEN -2147483648 AND 2147483647
WITH CHECK OPTION;
OBJECT
类型:当然,如果你真的想要一个类型,那么创建它!
CREATE OR REPLACE TYPE my_integer AS OBJECT (
i NUMBER(10),
CONSTRUCTOR FUNCTION my_integer (SELF IN OUT NOCOPY my_integer, i NUMBER)
RETURN SELF AS RESULT
) FINAL;
/
CREATE OR REPLACE TYPE BODY my_integer AS
CONSTRUCTOR FUNCTION my_integer (SELF IN OUT NOCOPY my_integer, i NUMBER)
RETURN SELF AS RESULT IS
BEGIN
IF i NOT BETWEEN -2147483648 AND 2147483647 THEN
raise_application_error(-20000, 'Not a 32 bit integer');
END IF;
SELF.i := i;
RETURN;
END;
END;
/
CREATE TABLE x (i my_integer);
现在,尝试插入这些。第二个将失败:
INSERT INTO x VALUES (my_integer(1));
INSERT INTO x VALUES (my_integer(9999999999));
如果您已正确规范化架构,则不会发生这种情况。只需创建
CREATE TABLE int4 (i NUMBER(10) PRIMARY KEY);
INSERT INTO int4
SELECT -2147483649 + level
FROM dual
CONNECT BY level <= 2 * 2147483648;
CREATE TABLE x (i NUMBER(10) REFERENCES int4);
适用于SMALLINT
和TINYINT
。如果您购买Exadata,那么您也可以尝试使用BIGINT
。确保没有人修改表格!
致Kjetil S.在评论中提供此想法的信用
我听说标准的SQL断言很可能是Oracle未来的一个特性:https://community.oracle.com/ideas/13028
他们喜欢CHECK
约束,但可以跨越几个表。当然,在您的情况下过度设计,但至少不是实际的CHECK
约束。
如果您愿意付费,并且您似乎希望通过而不是使用简单的检查约束来解决此问题,那么Oracle已通过Virtual Private Database功能对您进行了介绍
只是拒绝访问数据库用户所需范围之外的所有值,然后重新设置。
既然你没有提到任何关于你的动机的事情,那么,为什么不使用PostgreSQL作为你的Oracle数据库的接口呢?您可以在PostgreSQL中使用Oracle Foreign Data Wrapper的此实现,然后将表格声明为:
CREATE FOREIGN TABLE x (
id integer
) SERVER oracle_server OPTIONS (schema 'MY_USER', table 'X');
您将获得大量其他免费酷炫功能,例如:
FILTER
子句BOOLEAN
数据类型,而不是1
/ 0
无意义