【问题标题】:Unable to set precision for INTEGER data type in SQL CREATE TABLE command无法在 SQL CREATE TABLE 命令中设置 INTEGER 数据类型的精度
【发布时间】:2021-01-12 13:35:21
【问题描述】:

我正在尝试在 Oracle 中创建下表。

CREATE TABLE CUSTOMER(CUST_ID INT(10),
CUST_NAME   VARCHAR2(50),
CUST_SEX    CHAR(2),
CUST_STATE  VARCHAR2(50),
CUST_COUNTRY    VARCHAR2(50));

我收到一条错误消息,提示缺少右括号。实际上,问题在于 CUST_ID 列的 INT 数据类型。从 DDL 查询中删除精度 :(10) 后,我就能够成功执行它。

Oracle 文档没有指定关于此数据类型是否可以附带精度参数的任何内容。但是 Oracle 确实提到 INTEGER/INT 符合 ANSI 标准。

https://docs.oracle.com/cd/B19306_01/olap.102/b14346/dml_datatypes002.htm

某些其他非官方参考资料将 INT/INTEGER 描述为 NUMBER(38) 的同义词。

谁能告诉我是否确实不能为 INT 数据类型指定精度?

【问题讨论】:

  • 为什么你认为INTEGER 会支持精度? SQL 标准没有为INTEGER 定义精度参数,Oracle 也没有。

标签: oracle precision ddl create-table oracle18c


【解决方案1】:

Oracle docs 声明:

创建表和集群的 SQL 语句也可以使用来自 IBM 产品 SQL/DS 和 DB2 的 ANSI 数据类型和数据类型。 Oracle 识别不同于 Oracle 数据库数据类型名称的 ANSI 或 IBM 数据类型名称。它将数据类型转换为等效的 Oracle 数据类型

如下表所述,intinteger 和(令人惊讶?)smallint 都是 number(38) 的同义词,因此您无法为它们指定精度。对于你的用例,如果你想要一个十位数的整数,你应该使用number(10)

【讨论】:

    【解决方案2】:

    让我试一试:确实不能为 INT 数据类型指定精度。

    听起来怎么样?

    文档说:

    <snip>
    | { NUMERIC | DECIMAL | DEC } [ (precision [, scale ]) ]  --> precision + scale
    | { INTEGER | INT | SMALLINT }                            --> no precision for integers
    | FLOAT [ (size) ]
    <snip>
    

    【讨论】:

      【解决方案3】:

      在 Oracle 中,INT[EGER] 数据类型(至少大部分应该是 4 字节二进制整数)存在于 PL/SQL 存储过程中(如果有的话)。

      最好的办法是为 SMALLINT 设计一个 NUMBER(5),为 INTEGER 设计一个 NUMBER(9),为 LARGEINT/BIGINT 设计一个 NUMBER(18)

      如果你去:

      CREATE TABLE dropme (i INT);
      

      ,在 Oracle 中,您会得到一个包含 i NUMBER 列的表(没有指定长度,归结为一个非常低效的 NUMBER(38)。

      Oracle 数值数据类型为 NUMBER ,具有可选的总体精度和可选的小数位数,以及 FLOAT。

      而 Oracle NUMBER,至少在我的理解中,是一个可变长度构造,带有一个二进制、两字节、整个事物的长度指示符,后跟一个二进制十进制表示法,其中后面的每个半字节可以容纳 0000 和 1001 之间的二进制,或 09 - 除了最后一个,它包含符号:正/负。

      【讨论】:

      • 关于 NUMBER(38) 没有任何低效 - 请参阅我的答案。值 123 在 NUMBER(3) 和 NUMBER(38) 中占用相同的空间。
      • 对我来说,效率不仅限于存储空间。对于散列分组、排序或散列连接中的散列表,无法预测一个值是否在最多 38 位内没有占用整个空间,并且您可能会面临数量级的过度分配.并且要么在计算之前转换为整数,要么使用这些格式进行计算 - 无论哪种方式都会浪费 CPU 周期数个数量级......
      【解决方案4】:

      作为the documentation saysINTEGER 等价于NUMBER(38)

      您可以只使用INTEGER 来存储任何大小的整数,或者如果您想将值中的位数限制为n,则可以使用NUMBER(n)

      注意:在 Oracle 中指定精度的唯一原因是为了验证和记录。使用较小的 n 值没有空间优势:值 123456 在 NUMBER(6)NUMBER(38)INTEGER 列中占用相同数量的字节 - 即 4 个字节。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-02-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多