首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么oracle只显示VARCHAR数据类型的最大值9999?

为什么oracle只显示VARCHAR数据类型的最大值9999?
EN

Stack Overflow用户
提问于 2019-08-09 20:43:16
回答 4查看 389关注 0票数 2

我有一个表,其中我使用9 BYTE将列类型设置为VARCHAR,但在此列上应用max函数时,它仅显示最大值9999,并且不会超过这个值。

代码语言:javascript
运行
复制
create table test(
ID  NUMBER,
NAME    VARCHAR2(100 BYTE),
SAL NUMBER,
RANK    VARCHAR2(9 BYTE));

Insert into test (ID,NAME,SAL,RANK  ) values (1082,'ABC',2082,'9999');
Insert into test (ID,NAME,SAL,RANK  ) values (1083,'ABC',2083,'10000');

实际数据:

代码语言:javascript
运行
复制
id      NAME      SAL    RANK   
1082    ABC      2082   9999
1083    ABC      2083   10000

查询

代码语言:javascript
运行
复制
select * from test where RANK   =(select max(RANK   ) from testyy);

输出:

代码语言:javascript
运行
复制
id      NAME      SAL    RANK   
1082    ABC   2082       9999

我曾尝试将列设置为空,并将列修改为整数,然后它就起作用了,但我质疑为什么它不适用于9字节数据类型

代码语言:javascript
运行
复制
update test set RANK    =null where id=1082;
update test set RANK    =null where id=1083;
alter table test modify RANK    INTEGER;

update test set RANK    ='9999' where id=1082;
update test set RANK    ='10000' where id=1083;

select * from test where RANK   =(select max(RANK) from test);

id      NAME      SAL    RANK   
------------------------------------------
1083    ABC      2083   10000

没有来自Oracle SQL developer的错误消息

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-08-09 21:25:18

我贴出这个答案是为了纠正你对桌子设置的一个基本误解

您断言这条语句创建了一个数据类型为byte的列:

代码语言:javascript
运行
复制
CREATE TABLE X( Y VARCHAR2(100 BYTE) )

在通常理解的编程概念“一个字节是8位,存储一个介于0到255 (或0x00和0xFF)之间的数字”中,绝对与Bytes无关。

此列的数据类型为VARCHAR2,即文本。而不是字节。不是数字。非数字

BYTE的存在指示oracle使用最多100字节的存储空间来包含文本。这意味着如果您插入每个字符需要4个字节的Unicode字符,那么在oracle提示您的字符串太长之前,您只能在其中包含25个字符。如果您插入ascii字符,每个字符需要1个字节,那么在oracle告诉您字符串太长之前,您将得到100个字符

这里的BYTE补码是CHAR,它告诉oracle“只要接受长度不超过100个字符的字符串,就可以使用所需的磁盘空间”。这意味着oracle将使用磁盘上100到400字节的空间来存储字符。

-

其他的答案已经涵盖了为什么'9999‘的字符串“大于”一个'10000’的字符串,但我确实有一个金块可以补充为什么它是这样的:

作为字符的'9‘在ascii表中的位置为0x39,因此在数字上是“值”57 (十六进制0x39的基数10表示)

作为字符的'1‘在ascii表中的位置为0x31,因此在数值上是“table”49 ( 0x31十六进制的基数10表示)

当oracle比较字符串(使用从左到右的语言)并询问“哪个字符串按字母顺序排在另一个之后/更大?”它从左到右逐个比较字符

在他的例子中,它做的是第一个字符:

代码语言:javascript
运行
复制
Is '9' greater than '1'? 
--> What are the numeric representations of these characters? 57 and 49
--> Is 57 greater than 49? 
--> Yes. '9' is greater than '1'. 
--> STOP and declare '9999' is bigger than '10000'

它停止是因为不需要更多的比较。如果两个字符串都以'9‘开头,它们将并列比较第一个字符,oracle将继续比较第二个字符,以确定哪一个是胜利者。以此类推

现在你知道了: 9999和'9999‘没有任何关系--一个是数字,一个是看起来像数字的文本。此问题与基于数字的比较、字节的最大值等无关

它纯粹是关于字符串/文本是如何排序的,这就是您需要了解的内容

不要在varchar中存储您想要在数学上使用的数字;它们占用更多空间,速度更慢,并且每次使用它们时都会导致排序、数学和需要转换的错误

票数 1
EN

Stack Overflow用户

发布于 2019-08-09 20:47:16

因为在您的表中rank是varchar,并且在本例中9999大于10000,所以9999是最大的。

票数 6
EN

Stack Overflow用户

发布于 2019-08-09 20:49:14

当你按字符串排序时,你使用字典顺序,其中100在99之前(与'a‘在bb之前的方式相同),而当你按数字排序时,你会考虑它的值,所以100 > 90。

例如:

代码语言:javascript
运行
复制
SQL> create table testOrder (num number, str varchar2(10));

Table created.

SQL> insert into testOrder values (99, '99');

1 row created.

SQL> insert into testOrder values (100, '100');

1 row created.

SQL> select * from testOrder order by num;

       NUM STR
---------- ----------
        99 99
       100 100

SQL> select * from testOrder order by str;

       NUM STR
---------- ----------
       100 100
        99 99
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57430323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档