ORACLE---Unit02: Oracle字符串操作 、 Oracle数值操作 、 Oracle日期操作 、 空值操作

---DQL:数据查询语句
---SELECT语句中必须包含至少两个字句,分别是SELECT字句与FROM字句。
---SELECT子句用来指定要查询的字段,
---FROM子句用来定制数据来源的表。
--SELECT语句用来查询表中数据,一条SQL语句是由多个子句组成,
--一个子句有一个关键字加一系列内容组成。
--SELECT语句中必须含有的是两个子句,
--SELECT子句和FROM子句
--SELECT子句用于指定要查询的内容(字段,函数,表达式),
--FROM子句用来指定数据来源的表。
---SELECT中除了可以指定报表中具体字段外,还可以指定一个函数或表达式。
---*星代表所有字段
SELECT * FROM emp_RR;
SELECT empno,ename,job,sal FROM emp_RR;

-->查看每个员工的年薪
SELECT ename,sal,sal*12 FROM emp_RR;
---SELECT语句中添加WHERE字句,可以仅查询出满足条件的记录。
--->只看四个字段,只看部门号为20的。
SELECT ename,job,sal,deptno FROM emp_RR WHERE deptno=20;
--->工资大于2500
SELECT ename,job,sal,deptno FROM emp_RR WHERE sal>2500;
-->变成一列,java中的加号。连接号
SELECT CONCAT(ename,sal) FROM emp_RR;
---字符串函数
---CONCAT和"||"
---1.CONCAT(char1,char2)
---返回两个字符串连接后的结果,两个参数char1、char2是要连接的两个字符串。
---等价操作:连接操作符"||"
---如果char1和char2任何一个为NULL,相当于连接了一个空格
SELECT CONCAT(ename,sal)FROM emp_RR;
SELECT CONCAT(CONCAT(ename,':'),sal)FROM emp_RR;
---多个字串连接,用||更直观
SELECT ename||':'||sal FROM emp_RR;
--->SMITH的工资是800所在部门号为20
SELECT ename||':'||sal||':'||deptno FROM emp_RR WHERE ename='SMITH' AND deptno=20;
--->LENGTH函数:字符串长度(个数)
 ---对CHAR来说,没有意义,因为CHAR是定长。
 ---2.LENGTH(char)
 ---用于返回字符串的长度
 ---如果字符类型是VARCHAR2,返回字符的实际长度
 ---如果字符类型是CHAR,长度还要包括后补的空格
 ---获取指定字符串的长度
--->查看每个员工名字的字符个数?
SELECT ename,LENGTH(ename) FROM emp_RR;
--->名字为4个字母的员工?
SELECT ename FROM emp_RR WHERE LENGTH(ename)=4;
---3.LOWER,UPPER,INITCAP
---将字符串转换为全小写,全大写,首字母大写
---dual:伪表
---当查询的数据与任何表没有关系时,可以查询伪表,这样只会查询出一条记录。
SELECT UPPER('helloworld')FROM emp_RR;
--->出现14条数据,从自己表内查。
---dual:伪表,当查询的内容不是任何表中数据时,可以用伪表代替。
---在INITCAP中,支持显示空格。
SELECT
  UPPER('helloworld'),
  LOWER('HELLOWORLD'),
  INITCAP('HELLO WORLD')
FROM dual;
---屏蔽大小写应用:
---如果是要转换大小写,在字母前加UPPER()或LOWER().
SELECT ename,sal,deptno FROM emp_RR WHERE UPPER(ename)=UPPER('scott');
---4.TRIM,LTRIM,RTRIM
---去除两边的空白,空白是空格的一种,数据库中更强劲点,你想去啥就去啥。
--->去除字符串两侧的指定字符内容
SELECT TRIM('e' FROM 'eeeeeliteeeee')FROM dual;
--->lit
SELECT
LTRIM('estestestestliteeeeeee','est')
FROM dual;
--->liteeeeeee
SELECT
RTRIM('estesetsetsetsliteeeeeeeeeee','e')
FROM dual;
--->estesetsetsetslit
SELECT
LTRIM('esfffrfsfefliteseseses','efs')
FROM dual;
--->rfsfefliteseseses
---只要字符串中有其中之一,左边的字符都被干掉。
---5.LPAD(char1,n,char2),RPAD
---补位函数,将char1显示n位,若char1不足n位时,左(右)补充若干个char2字符已达到位数。
SELECT ename,sal,LPAD(sal,15,'$')FROM emp_RR;
---LPAD、RPAD补位函数(左右补$符号)写3的话,超出部分会被删除。
SELECT ename,sal,RPAD(sal,3,' ')FROM emp_RR;
---6.SUBSTR(char,m[,n])
---方括号里面的内容是可有可无的
---截取char字符串,从m处开始,连续截取n个字符。
---需要注意:数据库中下标都是从1开始的!!!
---n若不指定或指定的数字超过可以截取的实际字符长度时,都是截取到当前字符串末尾。n是长度。
---若m为负数,则是从倒数位置开始截取。末尾数字不能为负数.
SELECT SUBSTR('thinking in FROM dual;
--->in
SELECT SUBSTR('thinking in FROM dual;
--->in
--->n=-2是null
---7.INSTR(char1,char2[,n[,m]])
---查看char2在char1中的位置,n和m不指定默认都是1
---n表示从第几个字符开始查找
---m表示查看第几次出现
SELECT INSTR('thinking in FROM dual;
--->3
SELECT INSTR('thinking in FROM dual;
--->3,还是3
SELECT INSTR('thinking in FROM dual;
--->6
SELECT INSTR('thinking in FROM dual;
--->10
SELECT INSTR('thinking in FROM dual;
--->0
--->java中没有返回-1,oracle中返回0.
---需要注意:数据库中下标都是从1开始的!!!0表示没有了。

---数值类型:
---1.NUMBER(P)表示整数
---完整语法:NUMBER(Precision,scale)
 --如果没有设置scale,则默认取值0,即NUMBER(p)表示整数
 --P表示数字的总位数,取值为1-38
---用来在表中存放如编码、年龄、次数等用整数记录的数据
CREATE TABLE student_RR(
 id NUMBER(4),
 name CHAR(20)
);
DESC student_RR
---2.NUMBER(P,S)表示浮点数
---NUMBER(precision,scale)
 --precision:NUMBER可以存储的最大数字长度(不包括左右两边的0)
 --scale:在小数点右边的最大数字长度(包括左侧0)
 --指定了s但是没有指定p,则p默认为38,如:
 --列明number(*,s)
 --经常用来做表中存放金额、成绩等有小数位的数据
CREATE TABLE student_RR(
id NUMBER(4),
name CHAR(20),
score NUMBER(5,2)
);
DESC student_RR
---NUMBER的变种数据类型:内部实现是NUMBER,可以将其理解为NUMBER的别名,目的是多种数据库及编程语言兼容
 --numeric(p,s):完全映射至NUMBER(p,s)
 --decimal(p,s)或DEC(p,s):完全映射至NUMBER(p,s)
 --integer或int:完全映射至NUMBER(38)类型
 --smallint:完全映射至NUMBER(38)类型
 --float(b):映射至NUMBER类型
 --double precision:映射至NUMBER类型
 --real:映射至NUMBER类型

 ---数字函数
 --1.ROUND(n[,m])
 --保留n小数点后m位。
 --m不写默认为0,即:保留到整数位
 --m若为负数,则是保留10位以上的数字
 
 --ROUND(m,n):四舍五入(武则天:5则天以为)
 --保留m到小数点后n位
 --n为0或不指定这是保留到整数
 --n为负数这是保留到小数点前的位数
 SELECT ROUND(45.678,2)FROM DUAL;
 --->45.68
 SELECT ROUND(45.678,0)FROM DUAL;
 --->46
 SELECT ROUND(45.678,-1)FROM DUAL;
 --->50
 ---负数-1就是看个位,进10位
SELECT ROUND(45.678,-2)FROM DUAL;
 --->0
SELECT ROUND(55.678,-2)FROM DUAL;
--->100
---2.TRUNC(n[,m])
---截取数字
---参数意义与ROUND一致
---不进行四舍五入,直接截取数字
SELECT TRUNC(45.678,2)FROM dual;
--->45.67
SELECT TRUNC(45.678,0)FROM dual;
--->45
SELECT TRUNC(45.678,-1)FROM dual;
--->40
SELECT TRUNC(45.678,-2)FROM dual;
--->0
SELECT TRUNC(55.678,-2)FROM DUAL;
--->0
---3.MOD
---求余数,相当于
---m除以n求余数,n若为0则直接返回m
---MOD(m,n):返回m除以n后的余数
---n为0则直接返回m
---薪水值按1000取余数
SELECT ename,sal,MOD(sal,1000)FROM emp_RR;
---4.CEIL和FLOOR:向上取整,向下取整
---硬是翻译过来是:天花板和地板
---n就是个整数值
SELECT CEIL(45.678)FROM DUAL;
--->46
SELECT FLOOR(45.678)FROM DUAL;
--->45
---日期类型相关函数:
---日期相关关键字:
---1.SYSDATE:返回一个表示当前系统时间的DATE的值
---2.SYSTIMESTAMP:返回当前时间的时间戳类型值
SELECT SYSDATE FROM dual;
--->22-8月 -17
SELECT SYSTIMESTAMP FROM dual;
--->22-8月 -17 03.42.51.562000000 下午 +08:00

--INSERT INTO emp(ename,hiredate) VALUES ('jack',SYSDATE);
---日期转换函数
---1:TO_DATE()
---将给定字符串按照给定的日期格式解析为一个DATE值
---日期格式字符串中不是字母或符号的其他字符都需要使用双引号括起来。
---单引号:表示字符串
SELECT TO_DATE('1990-09-13 21:55:21','YYYY-MM-DD HH24:MI:SS')FROM dual;
--->13-9月 -90
SELECT TO_DATE('1990年09月13日 21时55分21秒',
              'YYYY"年"MM"月"DD"日" HH24"时"MI"分"SS"秒"')FROM dual;
--->13-9月 -90
---注意:RR与YY是有区别的,RR与YY都是用两位数字表示年,但是
---当使用TO_DATE函数将两位数字解析为实际日期时,RR会自行判定实际,而YY不会。
SELECT TO_DATE('99-09-13','YY-MM-DD')FROM dual;
--->13-9月 -99
SELECT TO_CHAR(TO_DATE('99-10-18','YY-MM-DD'),'YYYY-MM-DD')FROM dual;
--->2099-10-18
--->见图sys和user世纪对比图:
SELECT TO_CHAR(TO_DATE('49-10-21','RR-MM-DD'),'YYYY-MM-DD')FROM dual;
--->2049-10-21
SELECT TO_CHAR(TO_DATE('61-10-21','RR-MM-DD'),'YYYY-MM-DD')FROM dual;
--->1961-10-21
---2.TO_CHAR函数
---将其它类型的数据转换为字符类型
SELECT TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS')FROM dual;
--->2017-08-22 16:07:35
---日期可以进行计算
---1.对一个日期加减一个数字,等同于计算加减天数
---2.两个日期相减,差为相差的天数
---日期之间比大小,越晚的越大。
---查看100天以后是哪天?
SELECT SYSDATE+100 FROM dual;
--->30-11月-17
---查看每个员工入职到今天为止共多少天?
SELECT ename,SYSDATE-HIREDATE FROM emp_RR;
--->一万三多天,大部分是八几年入职的。

---日期常用函數:
---1.LAST_DAY(date)
---返回給定日期所在月的月底日期
---LAST_DAY(date):返回日期date所在月的最后一天
---在按照自然月计算某些业务逻辑,或者安排月末周期性活动时很有用处
---查看当前日期月底?
SELECT LAST_DAY('20-2月-09')FROM DUAL;
--->28-2月 -09
---查看当月月底?
SELECT LAST_DAY(SYSDATE)FROM dual;
--->31-8月 -17
SELECT ename,LAST_DAY(hiredate)FROM emp_RR;
--->每位员工入职当月月底时间。
---2.ADD_MONTHS(date,i)
---对指定日期加上指定月,若i为负数则是减去
---ADD_MONTHS(date,i):返回日期date加上i个月后的日期值
--参数i可以是任何数字,大部分时候取正值整数
--如果i是小数,将会被截取整数后再参与运算
--如果i是负数,则获得的是减去i个月后的日期值
--计算职员入职20周年纪念日
SELECT ename,ADD_MONTHS(hiredate,20*12)as "20周年" FROM emp_RR;
---查看每个员工的转正日期?
SELECT ename,ADD_MONTHS(hiredate,3)FROM emp_RR;

---3.MONTHS_BETWEEN(date1,date2)
---计算两个日期之间相差多少个月,计算方式使用date1-date2得到的。
--查看每个员工入职到今天为止共多少个月?
SELECT ename,MONTHS_BETWEEN(SYSDATE,hiredate)FROM emp_RR;
---4.NEXT_DAY(date,i)
---返回给定日期第二天开始算一周之内指定周几对应的日期
---NEXT_DAY(date,i)
---返回给定日期第二天开始一周内的周几的日期。i表示周几:
---1为周日。2为周一,以此类推。
SELECT NEXT_DAY(SYSDATE,6)FROM dual;
--->25-8月 -17
--NEXT_DAY(date,char):返回date日期数据的下一个周几,周几是由参数char来决定的
--在中文环境下,直接使用“星期三”这种形式,英文环境下,需要使用“wednesday”
--这种英文的周几。为避免麻烦,可以直接用数字1-7表示周日-周六
--NEXT_DAY不是明天!
--查询下个周三是几号
SELECT NEXT_DAY(SYSDATE,4)as "NEXT_WEDN" FROM DUAL;
--->23-8月 -17 ??????????????????????????????????????????????????????????????????????
---查询下个周三是几号?
---昨天输出执行是今天的日期???今天输出执行是下周三的日期。(此部分还需要在研究研究)
--->30-8月 -17
SELECT NEXT_DAY(SYSDATE,4)as NEXT_WEDN FROM dual;
--->23-8月 -17
--->30-8月 -17
SELECT NEXT_DAY(SYSDATE,5)as NEXT_WEDN FROM dual;
--->24-8月 -17
---NEXT_DAY 查询下个n是几号?
---按照国外的周概念查询,按照中国的就要加一。
SELECT NEXT_DAY(TO_DATE('2017-03-01','YYYY-MM-DD'),7)FROM dual;
---5.LEAST和GREATEST
---最小值与最大值,凡是可以比较大小的数据类型都可以使用这两个函数
---对于日期当中,最大值即最晚的日期,最小值即最早的日期
---GREATEST(expr1[,expr2[,expr3]]...)
---LEAST(expr1[,expr2[,expr3]]...)
---也被称作比较函数,可以有多个参数值,返回结果是参数列表中最大或最小的值
---参数类型必须一致
---在比较值钱,在参数列表中第二个以后的参数会被隐含的转换为第一个参数的数据类型,
---所以如果可以转换,则继续比较,如果不能转换将会报错
SELECT LEAST(SYSDATE,'10-10月-08')FROM DUAL;
---> 10-10月-08
SELECT LEAST(SYSDATE,TO_DATE('2008-08-08','YYYY-MM-DD'))FROM dual;
--->08-8月 -08
SELECT GREATEST(SYSDATE,TO_DATE('2008-08-08','YYYY-MM-DD'))FROM dual;
--->23-8月 -17
---6.EXTRACT
---提取一个日期中指定时间分量的值
SELECT EXTRACT(YEAR FROM SYSDATE)FROM dual;
--->2017
---查看1980年入职的员工?
SELECT ename,sal,hiredate FROM emp_RR WHERE EXTRACT(YEAR FROM hiredate)=1980;
--->SMITH 800 17-12月-80
---EXTRACT(date FROM datetime):从参数datetime中提取参数date指定的数据,比如提取年、月、日
SELECT EXTRACT(YEAR FROM SYSDATE)CURRENT_YEAR FROM dual;
--->2017
SELECT EXTRACT(HOUR FROM TIMESTAMP'2008-10-10 10:10:10')FROM dual;
--->10

---NULL(空即是NULL,NULL即是空)
---数据库里的重要概念:NULL,即空值
---有时表中的某些字段值,数据未知或暂时不存在,取值NULL
---任何数据类型均可取值NULL
---空和空字符串
---空---客观上不存在;空字符串---客观存在看不见。
---(有一个字符串了,看不见。这就好比空气和真空,空字符串就好比空气,它客观是存在的,只不过你看不见,
--- NULL就是客观上根本不存在。计算机里NULL客观不存在,NULL在内存里根本没有,而字符串是以二进制存在的。)
---在Java中null和空字符串的区别?
---null:客观不存在,在内存里面没有。(真空)
---空字符串:客观在内存里面是有编码的,只不过显示出来时,看不见。(属于客观存在)(空气)
---好比空气和真空的概念,空气客观存在,只是你看不见。null是真空,客观不存在。
---空值操作:
---插入空值
CREATE TABLE student_R(id NUMBER(4),name CHAR(20),gender CHAR(1));
--->table STUDENT_R 已创建。
INSERT INTO student_R VALUES(1000,'李莫愁','F');
--->1 行已插入。
INSERT INTO student_R VALUES(1001,'林平之',NULL);
--->1 行已插入。(显式插入NULL值)
INSERT INTO student_R(id,name)VALUES(1002,'张无忌');
--->1 行已插入。(隐式插入NULL值)
SELECT * FROM student_R;
---2:更新NULL值
UPDATE student_R SET gender=NULL WHERE id=1000;
--->1 行已更新。
SELECT * FROM student_R;
ROLLBACK;
--->回退完成。
---作为条件判断NULL值:
---判断药使用IS NULL和IS NOT NULL 不能使用"="判断NULL.
DELETE FROM student_R WHERE gender=NULL;
SELECT *FROM student_R;
--->0 行已删除。
---NULL不是值,只能说是一种状态。从逻辑上讲,=null等于空,严格意义上是不对的。(数据库中比Java中要严谨)
---在数据库中,在判断一个字段的值是不是null时,不能写=nuul,因为没有任何值是=null的。
---注意:写is null
DELETE FROM student_R WHERE gender IS NULL;
--->2 行已删除。
DELETE FROM student_R WHERE gender IS NOT NULL;
--->1 行已删除。
---NULL的运算
---NULL与字符串连接等于什么也没干。
---NULL与数字运算,结果还是NULL
SELECT ename||NULL FROM emp_RR;
---JAVA中与字符串相连?
---Java中与字符串拼接,就真的拼了个null
---package oracle;
--public class Demo {
-- public static void main(String[]args){
--  String str=null;
--  System.out.println("str:"+str);
-- }
--}
--->str:null
---和数字运算,结果还是null。
---查看每个员工的收入(工资加绩效)
SELECT ename,sal,comm,sal+comm FROM emp_RR;
---空值函数
---1.NVL(a1,a2)
---当a1为NULL时,函数返回a2,否则返回a1自身,所有函数作用是将NULL值替换为指定值。
SELECT ename,sal,comm,sal+NVL(comm,0) FROM emp_RR;
---计算员工月收入
SELECT ename,sal,comm,sal+NVL(comm,0)as "salary"FROM emp_RR;
---查看每个员工的绩效,有绩效的则显示为“有绩效”为NULL的则显示为“没有绩效”。
---2.NVL2(a1,a2,a3)
---当a1不为NULL时,函数返回a2;当a1为NULL时,函数返回a3
SELECT ename,comm,NVL2(comm,'有绩效','没有绩效')FROM emp_RR;
---NVL2可以实现NVL的功能,但是NVL不能全实现NVL2的功能。
SELECT ename,sal,comm,sal+NVL(comm,0) FROM emp_RR;
SELECT ename,sal,comm,sal+NVL2(comm,comm,0) FROM emp_RR;
SELECT ename,sal,comm,NVL2(comm,sal+comm,sal) FROM emp_RR;
---NVL2(expr1,expr2,expr3):和NVL函数功能类似,都是将NULL转变为实际值
---NVL2用来判断expr1是否为NULL,如果不是NULL,返回expr2,如果是NULL,返回expr3.
SELECT ename,sal,comm,nvl2(comm,sal+comm,sal)as"salary"FROM emp_RR;
 
*******************************************************************************************
posted @ 2017-11-08 20:02  xiaoredhat  阅读(293)  评论(0编辑  收藏  举报