首页 > 代码库 > oracle数据类型及操作

oracle数据类型及操作

1. Oracle字符串操作

1.1 字符串类型

? CHAR和VARCHAR2类型

l CHAR存放定长字符,如果数据存不满指定长度则用空格补齐,CHAR类型浪费空间换取查询时间的缩短。

l VARCHAR2存放可变长字符,实际数据有多少长度则占多少,VARCHAR2节省空间,查询时间较CHAR类型要长。

? CHAR和VARCHAR2的存储编码

字符串在数据库中存储的默认单位是字节,也可显式指定为字符。

l CHAR(10),等价于CHAR(10 BYTE)

l 如果指定单位为字符:CHAR(10 CHAR),20个字节

l VARCHAR2(10),等价于VARCHAR2(10 BYTE)

l 指定单位为字符:VARCHAR2(10 CHAR),20个字节

每个英文字符占用一个字节,每个中文字符按编码不同,占用2-4个字节。

l ZHS16GBK:2个字节

l UTF-8:2-4个字节

? CHAR和VARCHAR2的最大长度

l CHAR类型最大长度为2000字节,即:CHAR(2000),最多保存2000个英文字符,1000个汉字(GBK)

l VARCHAR2最大长度为4000字节,即:VARCHAR2(4000),最多保存4000个英文字符,2000个汉字(GBK)

l CHAR如果不指定长度,默认为1个字节,VARCHAR2必须指定长度

? LONG和CLOB类型

l LONG类型可以认为是VARCHAR2的加长版,用来存储变长字符串,最多达2GB的字符串数据,但是LONG类型有诸多限制,不建议使用:

n 每个表只能有一个LONG类型列

n 不能作为主键

n 不能建立索引

n 不能出现在查询条件中等

l CLOB用来存储定长或变长字符串,最多达4GB的字符串数据,Oracle建议开发中使用CLOB替代LONG类型。

CREATE TABLE emp(

id NUMBER(4),

name CHAR(20),

detail CLOB

);

1.2 字符串函数

? CONCAT和”||”

l CONCAT是字符串连接函数,语法如下:

CONCAT(char1,char2)

用于返回两个字符串连接后的结果,concat只能有两参数,即只能连接两个字符串,三个字符串连接,需要使用两个CONCAT。

演示:以“姓名:工资”形式列出

SELECT CONCAT(CONCAT(ename,‘:‘),sal) FROM emp;

技术分享

l ||连接符号,可以连接多个字符串

演示:以“姓名:绩效:薪资”的形式列出

SELECT ename||‘:‘||comm||‘:‘||sal FROM emp;

技术分享

演示:以别名为empinfo的方式列出以上信息

SELECT ename||‘:‘||comm||‘:‘||sal AS empinfo FROM emp; --AS也可以省略

SELECT ename||‘:‘||comm||‘:‘||sal empinfo FROM emp;

技术分享

l 在连接时,如果任何一个参数是NULL,相当于连接了一个空格。

? LENGTH

LENGTH(char)用于返回参数字符串的长度。如果字符类型是VARCHAR2,返回字符的实际长度,如果是CHAR,长度还包括补齐的空格。

演示:查询员工姓名的长度

SELECT ename,LENGTH(ename) FROM emp;

技术分享

? UPPER、LOWER和INITCAP

l UPPER(char)用于将字符转换为大写形式

l LOWER(char)用于将字符串转换为小写形式

l INITCAP(char)用于将字符串中每个单词的首字母大写,其他字符小写,单词之间用空格和非字母字符分隔

l 如果这三个函数的输入参数是NULL值,仍然返回NULL值

演示:将hello world转换为大写、小写、首字母大写

SELECT UPPER(‘hello world‘),LOWER(‘HELLO WORLD‘),INITCAP(‘hello wORLD‘) FROM dual;

技术分享

? TRIM、LTRIM、RTRIM

l TRIM(c2 FROM c1)表示从c1的前后截去c2

l LTRIM(c1[,c2])表示从c1的左边(Left)截去c2

l RTRIM(c1[,c2])表示从c1的右边(Right)截去c2

后面两个函数中,如果没有参数c2就去除空格,其中最常用的是TRIM,经常用来去掉字符串前后的空格。

演示:以上三种用法演示

SELECT TRIM(‘e‘ from ‘elite‘) AS t1,LTRIM(‘elite‘,‘e‘) AS t2,RTRIM(‘elite‘,‘e‘) AS t3 FROM dual;

技术分享

演示:演示没有c2参数,去除空格

SELECT TRIM(‘e‘ from ‘elite‘) AS t1,LTRIM(‘ elite ‘) AS t2,RTRIM(‘ elite ‘) AS t3 FROM dual;

技术分享

? LPAD、RPAD

PAD即补丁,LPAD和RPAD两个函数都叫做补位函数。

l LPAD(char1,n,char2)左补位函数

l RPAD(char1,n,char2)右补位函数

在字符串参数char1的左边或右边用char2补足到n位,其中参数char2可重复多次。

演示:在sal列中用$补位位6位

SELECT ename,LPAD(sal,6,‘$‘) AS lp,RPAD(sal,6,‘$‘) AS rp FROM emp;

技术分享

? SUBSTR

SUBSTR表示在一个字符串中截取子字符串,语法如下:

SUBSTR(char,[m[,n]])

用于返回char中从m位开始截取n个字符的子串,字符串的首位计数从1开始。

l 如果m=0,则从首字母开始,如果m取负数,则从尾部开始

l 如果没有设置n,或者n的长度超过了char的长度,则取到字符串末尾为止

演示1:

SELECT SUBSTR(‘hello world‘,4,5) FROM dual;

技术分享

演示2:

SELECT SUBSTR(‘hello world‘,0,8) FROM dual;

技术分享

演示3:

SELECT SUBSTR(‘hello world‘,-4,2) FROM dual;

技术分享

演示4:

SELECT SUBSTR(‘hello world‘,2) FROM dual;

技术分享

演示5:

SELECT SUBSTR(‘hello world‘,0,100) FROM dual;

技术分享

? INSTR

用来返回一个字符串中子字符串的位置,语法是:

INSTR(char1,char2[,n[,m]])

l 返回子串char2在源字符串char1中的位置

l 从n的位置开始搜索,没有指定n,从第1个字符开始搜索

l m用于指定子串的第m次出现次数,如果不指定则取值1

l 如果在char1中没有找到子串char2,返回0

演示1:

SELECT INSTR(‘hello world‘,‘o‘) FROM dual;

技术分享

演示2:

SELECT INSTR(‘hello world‘,‘o‘,6) FROM dual;

技术分享

演示3:

SELECT INSTR(‘hello world‘,‘o‘,9) FROM dual;

技术分享

演示4:

SELECT INSTR(‘hello world‘,‘o‘,-1) FROM dual;

技术分享

演示5:

SELECT INSTR(‘hello world‘,‘o‘,6,1) FROM dual;

技术分享

2. Oracle数值操作

2.1 数值类型

? 整数

NUMBER(p)表示整数,p表示数字的总位数,取值为1-38。

演示:学生id设置为4位整数

CREATE TABLE stedunt(id NUMBER(4));

? 浮点数

NUMBER(p,s)表示浮点数,含义如下:

l p:NUMBER可以存储的最大数字长度(不包括左右两边的0)

l s:表示小数位最大的数字长度(包括左侧的0)

l 如果指定了s但是没有指定p,则p默认为38

如:id NUMBER(*,s)

演示:设置员工薪资为6位数,小数位为2位,最大取值即9999.99

CREATE TABLE empx(sal NUMBER(6,2));

NUMBER的变种数据类型:内部实现是NUMBER,可以将其理解为NUMBER的别名,目的是多种数据库及编程语言兼容。

l NUMBER(p,s):完全映射至NUMBER(p,s)

l DECIMAL(p,s)或DEC(p,s):完全映射至NUMBER(p,s)

l INTEGER或INT:完全映射至NUMBER(38)类型

l SMALLINT:完全映射至NUMBER(38)类型

l FLOAT(b):映射至NUMBER类型

l DOUBLE PRECISION:映射至NUMBER类型

l REAL:映射至NUMBER类型

2.2 数值函数

? ROUND

ROUND用来四舍五入,语法如下:

ROUND(n,[,m])

用于将参数n按照m的数字要求四舍五入。

l 参数中的n可以是任意数字,指要被处理的数字

l m必须是整数

l m取整数则四舍五入到小数点后m位

l m取0则四舍五入到整数位

l m取负数则四舍五入到小数点前m位

l m缺省值为0

演示:

SELECT ROUND(45.678,2),ROUND(45.678,0),ROUND(45.678,-1) FROM dual;

技术分享

? TRUNC

TRUNC表示截取,语法如下:

TRUNC(n[,m])

n,m的含义同ROUND。

演示:

SELECT TRUNC(45.678,2),TRUNC(45.678,0),TRUNC(45.678,-1),TRUNC(45.678) FROM dual;

技术分享

? MOD

取余,语法如下:

MOD(m,n)

用于返回m除以n后的余数,如果n为0则直接返回m。

演示:薪水值按1000取余

SELECT ename,MOD(sal,1000) FROM emp;

技术分享

? CEIL和FLOOR

l CEIL(n):表示取大于或等于n的最小整数值

FLOOR(n):表示取小于或等于n的最大整数值

演示:

SELECT CEIL(45.678),FLOOR(45.678),CEIL(45), FLOOR(45)FROM dual;

技术分享

3. Oracle日期操作

3.1 DATE

DATE和TIMESTAMP是Oracle中最常用的日期类型。DATE用来保存日期和时间,表示范围是从公元前4712年1月1日至公元9999年12月31日。

DATE类型在数据库中的实际存储固定为7个字节,格式分别如下:

l 第1字节:世纪+100

l 第2字节:年

l 第3字节:月

l 第4字节:天

l 第5字节:小时+1

l 第6字节:分+1

l 第7字节:秒+1

? TIMESTAMP

TIMESTAMP表示时间戳,与DATE的区别是不仅可以保存日期和时间,还能保存小数秒,可指定0-9位,默认6位,最高精度可以到ns(纳秒)级别。

数据库内部用7或者11个字节存储,精度为0时,用7字节存储,与DATE功能相同,精度大于0则用11字节存储。格式如下:

l 第1-7字节:与DATE相同

l 第8-11字节:纳秒,采用4个字节存储,内部运算类型为整型

演示:

CREATE TABLE test(

c1 DATE,

c2 TIMESTAMP(9)

);

3.2 日期关键字

? SYSDATE

SYSDATE本质是一个Oracle的内部函数,用来返回当前的系统时间,精确到秒,默认显示格式是DD-MON-RR,只有年月日并不显示时间。

演示:

SELECT SYSDATE FROM dual;

技术分享

如果数据库是英文环境,将显示“27-JUN-17”的形式,如果是中文环境,将显示“27-6月-17”的形式。

如果想显示时分秒,需要将格式转换一下,使用TO_CHAR转换。

演示:

SELECT TO_CHAR(SYSDATE,‘yyyy-mm-dd day hh24:mi:ss‘) FROM dual;

技术分享

? SYSTIMESTAMP

SYSTIMESTAMP也是Oracle的内部日期函数,返回当前系统日期和时间,精确到毫秒。

演示:

SELECT SYSTIMESTAMP,TO_CHAR(SYSTIMESTAMP,‘SSSS.FF‘) FROM dual;

技术分享

3.3 日期转换函数

日期数据有时需要和字符串数据相互转换,需要用到日期转换函数,包括TO_CHAR和TO_DATE。

? TO_DATE

TO_DATE的功能是将字符串按照定制格式转换为日期类型,语法如下:

TO_DATE(char[,fmt[,nlsparams]])

其中:char是要转换的字符串,fmt是转换格式,nlsparams是指定日期语言。常用的格式如下:

格式

含义

YY

2位数字的年份

YYYY

4位数字的年份

MM

2位数字的月份

MON

简拼的月份

MONTH

全拼的月份

DD

2位数字的天

DY

周几的缩写

DAY

周几的全拼

HH24

24小时制的小时

HH12

12小时制的小时

MI

显示分钟

SS

显示秒

演示:查询1982年以后入职的员工

SELECT ename,hiredate FROM emp WHERE hiredate>TO_DATE(‘1982-01-01‘,‘YYYY-MM-DD‘);

技术分享

? TO_CHAR

TO_CHAR的作用是将其它类型(日期,数值)的数据转换为字符类型,主要应用在日期类型上,语法如下:

TO_CHAR(date[,fmt[,nlsparams]])

其中fmt是格式,将日期类型数据date按照fmt格式输出字符串,nlsparams用于指定日期语言。

演示:将员工的hiredate转换为年月日的形式显示

SELECT ename,hiredate,TO_CHAR(hiredate,‘YYYY"年"MM"月"DD"日"‘) FROM emp;

技术分享

3.4 日期常用函数

? LAST_DAY

语法:

LAST_DAY(date)

返回日期date所在月的最后一天,一般是按照自然月计算某些业务逻辑,或者安排月末周期性活动时用到。

演示:

SELECT LAST_DAY(SYSDATE) FROM dual; --查询当月的最后一天

SELECT LAST_DAY(‘20-2月-2000‘) FROM dual; --查询2000年2月最后一天

? ADD_MONTHS

语法:

ADD_MONTHS(date,i)

返回日期date加上i个月后的日期值。

l 参数i可以是任何数字,大部分时候取正值整数

l 如果i是小数,将会截取整数后在参与运算

l 如果i是负数,则获取减去i月后的日期值

演示:计算入职员工20周年纪念日

SELECT ename,ADD_MONTHS(hiredate,12*20) FROM emp;

技术分享

? MONTHS_BETWEEN

语法:

MONTHS_BETWEEN(date1,date2)

用于计算date1和date2两个日期之间间隔了多少个月,实际运算是date1-date2,如果date2时间比date1晚,则会得到负值。

除非两个日期间隔是整数月,否则会得到带小数位的结果。

演示1:date1比date2大整数月

SELECT MONTHS_BETWEEN(‘09-9月-2008‘,‘09-10月-2007‘) FROM dual;

技术分享

演示2:date1比date2小整数月

SELECT MONTHS_BETWEEN(‘09-9月-2006‘,‘09-10月-2007‘) FROM dual;

技术分享

演示3:date1比date2小非整数月

SELECT MONTHS_BETWEEN(‘21-9月-2006‘,‘09-10月-2007‘) FROM dual;

技术分享

? NEXT_DAY

语法:

NEXT_DAY(date,char)

返回date日期数据的下一个周几,周几是由参数char来决定的。在中文环境下,直接使用“星期三”这种格式,英文环境下,需要使用“WEDNESDAY”这种格式。为避免麻烦,可以直接使用1-7来表示周日-周六。

演示:17年6月27号的下一个周三是哪天

SELECT NEXT_DAY(‘27-6月-17‘,4) FROM dual;

技术分享

? LEAST、GREATEST

语法:

LEAST(expr1[,expr2[,expr3]]…) --返回最小值

GREATEST(expr1[,expr2[,expr2]]…) --返回最大值

两个函数都可以有多个数值,但参数类型必须一致,返回结果是参数列表中最大或最小的值,在比较之前,在参数列表中第二个以后的参数会被隐含的转换为第一个参数的数据类型,所以如果可以转换,则继续比较,如果不能转换将会报错。

演示:

SELECT LEAST(SYSDATE,‘10-10月-09‘),GREATEST(SYSDATE,‘10-10月-09‘) FROM dual;

技术分享

? EXTRACT

语法:

EXTRACT(date FROM datetime)

从参数datetime中提取参数date指定的数据,比如提取年、月、日。

演示:取出年

SELECT ename,EXTRACT(YEAR FROM hiredate) FROM emp;

技术分享

4. 空值操作

NULL是数据库里的重要概念,即空值。当表中的某些字段值,数据未知或暂时不存在,取值NULL。

Java中简单的数据类型是不能取值NULL的,在数据库中,任何数据类型均可取值NULL。

? 插入NULL值

在数据表中,如果要插入NULL值,可以采用显示指定NULL值方式,或者不插入某个字段值,即隐式表示NULL值。

演示:

CREATE TABLE student(

id NUMBER(4),

name CHAR(20),

gender CHAR(1)

);

INSERT INTO student VALUES(1000,‘李莫愁‘,‘F‘);

INSERT INTO student VALUES(1001,‘林平之‘,NULL); --显示插入NULL值

INSERT INTO student (id,name) VALUES(1002,‘东方不败‘); --隐式插入NULL值

技术分享

? 更新成NULL值

把数据的某个字段更新为NULL值,和更新为其他数据方法相同,需要和WHERE配合使用,不然全表都会被更新为NULL值。

演示:

UPDATE student SET name=NULL; --全表都被更新

技术分享

注意这种更新只有在此列没有非空约束的情况下才可操作。如果该列有非空约束,则无法更新为NULL值。

? NULL条件查询

在条件查询中,因为NULL不等于任何值,所以不能用“=“,必须用”IS NULL“或”IS NOT NULL”来判断。

演示:

SELECT name,gender FROM student WHERE gender IS NOT NULL;

SELECT name,gender FROM student WHERE gender IS NULL;

? 非空约束

非空(NOT NULL)约束是约束条件的一种,用于确保数据表中某个字段值不为空。

因为在默认情况下,任何数据的列都允许有空值,但系统业务逻辑可能会要求某些列不能取空值,这时需要在建表时指定该列不允许为空。

一旦某个字段被设置了非空条件约束,这个字段必须存在有效值。即:当执行插入数据操作时,必须提供这个列的数据,当执行更新操作时,不能给这个列的值设置为NULL。

演示:

ALTER TABLE student MODIFY(NAME NOT NULL);

4.1 控制函数

? NVL

语法:

NVL(expr1,expr2)

将NULL转变为非NULL。如果expr1为NULL,则取值expr2,expr2是非空值。

其中expr1和expr2可以是任何数据类型,但两个参数的数据类型必须是一致的。

任何数与NULL做计算,最后都是NULL。如果计算员工月收入,如果comm为NULL 的话则收入为空,不符合逻辑,所以先将是NULL值的comm转换为0,再做相加。

演示:计算员工月收入,薪资+绩效

SELECT ename,sal,comm,sal+NVL(comm,0) 月收入 FROM emp;

技术分享

? NVL2

语法:

NVL2(expr1,expr2,expr3)

和NVL函数功能类似,都是将NULL转变为非空值。NVL2用来判断expr1是否为NULL,如果不是NULL,返回expr2,如果是NULL,返回expr3。

演示:查询员工月收入

SELECT ename,sal,comm,NVL2(comm,sal+comm,sal) AS 月收入 FROM emp;

技术分享

oracle数据类型及操作