数据库基本功之SQL的数据类型
数据库基本功之SQL的数据类型
1.四种基本的常用数据类型
1.1 字符型
char # 固定字符,最长2000个
varchar2 # 可变长字符,最长4000个,最小值是1
nchar/nvarchar2 # 类型的列使用国家字符集
raw & long raw # 固定/可变长度的二进制数据长度 最2G,可存放多媒体图象声音等.(老类型,逐步淘汰)
LONG # 可变长的字符串数据,最长2G,LONG具有VARCHAR2列的特性,一个表中最多一个LONG列.
# (老类型,逐步淘汰).建议使用大对象
表名要大写
-- 查看表的列名和字符类型
SELECT table_name, column_name, data_type FROM all_tab_cols WHERE table_name = 'EMP';
-- (表属组\表名\列名\字段类型\字段长度)
SELECT owner,table_name,column_name,data_type,data_length
FROM all_tab_columns
where table_name='EMP' and owner='scott' order by column_id;
SELECT owner,table_name,column_name,data_type,data_length
FROM all_tab_columns
where table_name='EMP';
1.1.1 eg1.char
SQL> create table a(a1 char(6));
Table created.
SQL> alter table a modify a1 char(4);
Table altered.
SQL> insert into a values('a');
1 row created.
SQL> commit;
Commit complete.
SQL> alter table a modify a1 char(3);
alter table a modify a1 char(3)
*
ERROR at line 1:
ORA-01441: cannot decrease column length because some value is too big
SQL> insert into a values('aaaaa');
insert into a values('aaaaa')
*
ERROR at line 1:
ORA-12899: value too large for column "SYS"."A"."A1" (actual: 5, maximum: 4)
SQL>
1.1.1 【eg2.nchar】
nchar:对字符和汉字一视同仁,可转换字符,安装中文字符
SQL>
SQL> create table b (b1 nchar(4));
Table created.
SQL> insert into b values('aaaa');
1 row created.
SQL> insert into b values('aaaaa');
insert into b values('aaaaa')
*
ERROR at line 1:
ORA-12899: value too large for column "SYS"."B"."B1" (actual: 5, maximum: 4)
SQL> insert into b values('我们都是');
1 row created.
SQL>
1.2 数值型
1.2.1 NUMBER (p, s)
定义格式NUMBER (precision,scale)
1.precision表示数字中的有效位;如果没有指定precision的话,Oracle将使用38作为精度.
2.如果scale>0,表示数字精确到小数点右边的位数;
scale默认设置为0;
如果scale<0,Oracle将把该数字取舍到小数点左边的指定位数.3.Precision的取值范围为【1---38】;
Scale的取值范围为【-84---127】.4.NUMBER整数部分允许的长度为(precision- scale),无论scale是正数还是负数.
5.如果precision小于scale,表示存储的是没有整数的小数.
6.Precision表示有效位数,有效数位:从左边第一个不为0的数算起,小数点和负号不计入有效位数;
scale表示精确到多少位,指精确到小数点左边或右边多少位(+-决定).
关于number的精度(p)和刻度(s)遵循以下规则:
1.当一个数的整数部分的长度> p-s 时,Oracle就会报错
2.当一个数的小数部分的长度> s 时,Oracle就会舍入.
3.当s(scale)为负数时,Oracle就对小数点左边的s个数字进行舍入.
4.当s > p 时, p表示小数点后第s位向左最多可以有多少位数字,如果大于p则Oracle报错,小数点后s位向右的数字被舍入
1.2.2 NUMBER类型的子类
1.oracle本来就没有int类型,为了与别的数据库兼容,新增了int类型作为number类型的子集.
2.int类型只能存储整数;number可以存储浮点数,也可以存储整数.
3.在oracle数据库建表的时候,decimal,numeric不带精度,oracle会自动把它处理成INTEGER;带精度,oracle会自动把它处理成number.
4.Oracle只用NUMBER(m,n)就可以表示任何复杂的数字数据.
5.decimal,numeric,int等都为SQL、DB2等数据库的数据类型,ORACLE为了兼容才将其引入;但实际上在ORACLE内部还是以NUMBER的形式将其存入.
1.2.3 Number自增
不同于mysql可以直接设置自增,需要建立序列,和触发器.例
1.2.3.1 创建表
SQL> CREATE TABLE example (ID Number(4) NOT NULL PRIMARY KEY,NAME VARCHAR(25));
Table created.
SQL> INSERT INTO example (id,name) values(222,'Lincoln');
1 row created.
SQL> select * from example;
ID NAME
---------- ---------------------------------------------------------------------------
222 Lincoln
SQL>
1.2.3.2 建立序列(sequence)
CREATE SEQUENCE example_sequence INCREMENT BY 1 START WITH 1 NOMAXVALUE NOCYCLE NOCACHE; -- slpdeveloper中执行------------ CREATE SEQUENCE example_sequence INCREMENT BY 1 -- 每次加几个 START WITH 1 -- 从1开始计数 NOMAXVALUE -- 不设置最大值 NOCYCLE -- 一直累加,不循环 NOCACHE -- 不建缓冲区
SQL>
SQL> create sequence example_sequence increment by 1 start with 1 NOMAXVALUE NOCYCLE NOCACHE;
Sequence created.
SQL>
1.2.3.3 创建触发器
SQL> CREATE OR REPLACE TRIGGER example_t
2 BEFORE INSERT ON example
3 FOR EACH ROW
4 BEGIN
5 SELECT example_sequence. nextval INTO: new.id FROM dual;
6 END;
7 /
Trigger created.
SQL> show user;
USER is "SCOTT"
SQL>
SQL>-- 删除触发器
SQL>drop TRIGGER example_t;
1.2.3.4 插入数据
insert into example (name) values('klaus');
insert into example (id, name) values(101,'Lincoln');
-- number自增,无需指定ID,如klaus,此处指定的id’101’仍然被自增长
SQL> select * from example;
ID NAME
---------- ----------------
1 klaus
2 Lincoln
101 Lincoln
drop sequence sequencename; -- 删除sequence
drop TRIGGER example_t; -- 删除触发器
drop table a purge; -- 删除表
1.3 日期型
Date # 日期的普通形式,表示精度只能到秒级.
Timestamp # 日期的扩展形式,表示精度可达秒后小数点9位(10亿分之1秒).
timestamp with timezone # 带时区
timestamp with local timezone # 时区转换成本地日期
系统安装后,默认日期格式是DD-MON-RR, RR和YY都是表示两位年份,但RR是有世纪认知的,它将指定日期的年份和当前年份比较后确定年份是上个世纪还是本世纪(如表).
1.4 LOB型
大对象是10g引入的,在11g中又重新定义,在一个表的字段里存储大容量数据,所有大对象最大都可能达到4G
CLOB :用来存储单字节的字符数据,包含在数据库内.
NCLOB :用来存储多字节的字符数据,包含在数据库内.
BLOB :用于存储二进制数据,包含在数据库内.
BFILE :存储在数据库之外的二进制文件中,这个文件中的数据只能被只读访问,在操作系统下.
(知识点)CLOB,NCLOB,BLOB都是内部的LOB类型,没有LONG只能有一列的限制.
保存图片或电影使用BLOB最好、如果是小说则使用CLOB最好.
虽然LONG RAW也可以使用,但LONG是oracle将要废弃的类型,因此建议用LOB.
当然说将要废弃,但还没有完全废弃,比如oracle 11g里的重要视图dba_views,对于 text(视图定义)仍然沿用了LONG类型.
SQL>
SQL> create table t (id int, abc clob);
Table created.
SQL> insert into t values(1, 'klaus');
1 row created.
SQL> insert into t values(2, 'yao');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from t where abc='klaus';
select * from t where abc='klaus'
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected - got CLOB
SQL> select * from t where abc like 'klaus';
ID ABC
---------- --------------------------------------------------------------------------------
1 klaus
SQL>
【053内容】Oracle 11g重新设计了大对象,推出SecureFile Lobs的概念,相关的参数是db_securefile,采用SecureFile Lobs的前提条件是11g以上版本,ASSM管理等,符合这些条件的BasicFile Lobs也可以转换成SecureFile Lobs.较之过去的BasicFile Lobs, SecureFile Lobs有几项改进:
1)压缩,2)去重,3)加密.
当create table定义LOB列时,也可以使用LOB_storage_clause指定SecureFile Lobs或BasicFile Lobs,而LOB的数据操作则使用Oracle提供的DBMS_LOB包,通过编写PL/SQL块完成LOB数据的管理.
1.2 数据类型的转换
字符型、数值型、日期型之间的转换.
隐性类型转换和显性类型转换.
2.1 隐性类型转换:(不提倡)
是指oracle自动完成的类型转换.在一些带有明显意图的字面值上,可以由Oracle自主判断进行数据类型的转换.
-- empno 本来是数值类型的,这里字符’7788’隐性转换成数值7788
SQL>
SQL> select empno,ename from emp where empno='7788';
EMPNO ENAME
---------- ------------------------------
7788 SCOTT
-- 将data型隐性转成字符型后计算长度
SQL> select length(sysdate) from dual;
LENGTH(SYSDATE)
---------------
9
-- 将字符型’12.5’隐转成数字型再求和
SQL> select '12.5'+11 from dual;
'12.5'+11
----------
23.5
-- 将数字型11隐转成字符与’12.5’合并,其结果再隐转数字型与10求和
SQL> select 10+('12.5'||11) from dual;
10+('12.5'||11)
---------------
22.511
SQL>
2.2 显性类型转换是强制完成类型转换(推荐)
转换函数形式有三种:
TO_CHAR
TO_DATE
TO_NUMBERChar转date和number比较困难.date和number转char比较容易
2.2.1 日期-->字符
SQL> select ename,hiredate,to_char(hiredate, 'DD-MON-YY') month_hired from emp where ename='SCOTT';
ENAME HIREDATE MONTH_HIRED
------------------------------ --------------- ------------------------------------------------------
SCOTT 24-JAN-87 24-JAN-87
-- fm压缩空格或左边的’0’
SQL> select ename, hiredate, to_char (hiredate, 'fmyyyy-mm-dd') month_hired from emp where ename= 'SCOTT';
ENAME HIREDATE MONTH_HIRED
------------------------------ --------------- ------------------------------
SCOTT 24-JAN-87 1987-1-24
SQL>
-- 其实DD-MM-YY是比较糟糕的一种格式,因为当日期中天数小于12时,DD-MM-YY和MM-DDYY容易造成混乱.
2.2.2 数字-->字符
9表示数字,L本地化货币字符,其中'L99,999.99'.位数要足够
SQL> select ename,to_char(sal, 'L99,999.99') salary from emp where ename='SCOTT';
ENAME SALARY
------------------------------ ------------------------------------------------------------
SCOTT $3,000.00
SQL>
2.2.3 字符-->日期
-- ''内说明是char类型
SQL>
SQL> select to_date('1983-11-12', 'YYYY-MM-DD') from dual;
TO_DATE('1983-1
---------------
12-NOV-83
SQL>
2.2.4 字符-->数字
SQL> select to_number ('$123.45','$9999.99') result from dual;
RESULT
----------
123.45
SQL>
知识点:使用 to_number 时如果使用较短的格式掩码转换数字,就会返回错误.不要混淆 to_number和to_char转换.
SQL> select to_number ('123.56','999.9') from dual;
select to_number ('123.56','999.9') from dual
*
ERROR at line 1:
ORA-01722: invalid number
SQL> select to_char (123.56,'999.9') from dual;
TO_CHAR(123.56,'99
------------------
123.6
SQL>
更多推荐
所有评论(0)