我有一个表,其中我使用9 BYTE
将列类型设置为VARCHAR
,但在此列上应用max函数时,它仅显示最大值9999,并且不会超过这个值。
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');
实际数据:
id NAME SAL RANK
1082 ABC 2082 9999
1083 ABC 2083 10000
查询
select * from test where RANK =(select max(RANK ) from testyy);
输出:
id NAME SAL RANK
1082 ABC 2082 9999
我曾尝试将列设置为空,并将列修改为整数,然后它就起作用了,但我质疑为什么它不适用于9字节数据类型
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的错误消息
发布于 2019-08-09 21:25:18
我贴出这个答案是为了纠正你对桌子设置的一个基本误解
您断言这条语句创建了一个数据类型为byte的列:
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比较字符串(使用从左到右的语言)并询问“哪个字符串按字母顺序排在另一个之后/更大?”它从左到右逐个比较字符
在他的例子中,它做的是第一个字符:
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中存储您想要在数学上使用的数字;它们占用更多空间,速度更慢,并且每次使用它们时都会导致排序、数学和需要转换的错误
发布于 2019-08-09 20:47:16
因为在您的表中rank
是varchar,并且在本例中9999
大于10000
,所以9999
是最大的。
发布于 2019-08-09 20:49:14
当你按字符串排序时,你使用字典顺序,其中100在99之前(与'a‘在bb之前的方式相同),而当你按数字排序时,你会考虑它的值,所以100 > 90。
例如:
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
https://stackoverflow.com/questions/57430323
复制相似问题