視頻課程:李興華 Oracle從入門到精通視頻課程 學習者:陽光羅諾 視頻來源:51CTO學院 Oracle資料庫從入門到精通-單行函數 在資料庫中,為了方便用戶的數據開發,往往會提供一系列的支持函數,利用這些函數可以針對於數據處理。 例如:在進行根據姓名查詢的時候,如果說姓名本身是大寫字母,而查詢 ...
視頻課程:李興華 Oracle從入門到精通視頻課程
學習者:陽光羅諾
視頻來源:51CTO學院
Oracle資料庫從入門到精通-單行函數
在資料庫中,為了方便用戶的數據開發,往往會提供一系列的支持函數,利用這些函數可以針對於數據處理。
例如:在進行根據姓名查詢的時候,如果說姓名本身是大寫字母,而查詢的是小寫字母,此時就不會由任何的數據結果返回。所以針對於此類情況,往往數據保存的時候或者是查詢的時候對數據進行一些處理,而這些處理每一個資料庫都有自己本身的函數庫,利用函數可以實現特定的功能。
在Oracle中,對於函數的基本使用結構如下:
1 返回值 函數名稱(列|數據)
而根據函數的特點,單行函數可以分為以下幾種:字元串函數、數值函數、日期函數、轉換函數以及通用函數。
一、字元串函數
字元串函數可以針對於字元串數據進行處理,在Oracle之中對於此類函數定義有如下變化:UPPER()、LOWER()、INITCAP()、REPLACE()、LENGTH()、SUBSTR()。
1.大小寫轉換函數
轉大寫函數:字元串 UPPER(列|字元串)
轉小寫函數:字元串 LOWER(列|字元串)
如果要在Oracle資料庫中驗證字元串函數,那麼就必須保證編寫的是完整的SQL語句。所以為了可以方便地進行函數驗證,往往會使用一張虛擬表:dual表
範例:驗證函數
語法格式:
1 SELECT LOWER('SOLer He'),UPPER('SOLer He') FROM dual;
幾乎所有的資料庫裡面都會提供這兩個函數。
如果說現在要求用戶自己輸入一個雇員姓名,而後進行雇員信息的查找。
語法格式:
1 SELECT * FROM emp WHERE ename='&inputename';
結果如下:
用戶在進行數據輸入的時候幾乎不會去考慮大小寫,所以為了保證數據可以正常的查詢出來,往往需要對輸入數據進行處理。由於在數據表中所有的數據都是大寫操作,那麼就可以接收完輸入數據之後將會自動變為大寫字母。
範例:改善輸入操作。
語法格式:
1 SELECT * FROM emp WHERE ename=UPPER('&inputename');
所以在一些要求嚴格的操作環境下,對於不區分大小寫的操作的時候,基本上就會有兩種做法:
- 在數據保存的時候將所有的數據統一變為大寫或者是小寫,這樣子在查詢的時候就可以直接利用特定的函數進行處理。
- 在數據保存的時候依然是按照原始的方式進行保存,而後在查詢的時候將每一個數據中的字母變為大寫形式進行處理。
在所有不區分大小寫的操作的項目之中,保存數據時就必須對數據進行提前的處理。
2.首字母大寫
語法格式:
1 字元串 INITCAP(列 | 數據)
範例:觀察首字母大寫
代碼格式:
1 SELECT INITCAP ('HeLLoWorld') FROM dual;
查詢輸出結果:
除了首字母大寫之外,其他的都是小寫。
範例:將每一個雇員的姓名首字母變為大寫。
代碼結構:
1 SELECT INITCAP (ename) FROM emp;
查詢結果:
3.計算字元串長度
語法:
1 數字 LENGTH (列 | 字元串數據)
範例:查詢出每個雇員姓名以及雇員姓名的長度。
代碼格式:
1 SELECT ename,LENGTH(ename) FROM emp;
查詢結果:
那麼所有的單行函數可以在SQL語句的任意位置上出現。
範例:查詢雇員姓名長度為5的全部雇員信息。
分析:需要針對於所選的數據行進行篩選,那麼就一定要在WHERE子句之中進行。
代碼格式:
1 SELECT * FROM emp WHERE LENGTH(ename)=5;
結果如圖:
4.字元串的替換操作
可以使用指定的內容替換原始字元串中的數據。
語法格式:
1 字元串 REPLACE (列 | 數據,要查找的內容,新的內容)
範例:將所有雇員姓名之中的字母替換為“_”。
代碼示例:
1 SELECT REPLACE (ename,'A','_') FROM emp;
查詢結果:
實際上可以利用REPLACE()函數可以消除字元串中的全部空格數據。
範例:消除空格數據。
代碼示例:
1 SELECT REPLACE('Hello World This is my oracle',' ','') FROM dual;
查詢結果:
5.字元串截取
語法一:字元串 SUBSTR(列 | 數據,開始點),從指定的開始點一直截取到結尾
語法二:字元串 SUBSTR(列 | 數據,開始點,長度):截取指定範圍的子字元串。
範例:子字元串截取操作。
代碼示例:
1 SELECT SUBSTR('helloworldnihao',11) FROM dual;
查詢截圖:
此種方式就是從指定位置截取到結尾。
範例:截取部分內容
代碼示例:
1 SELECT SUBSTR('helloworldnihao',6,5) FROM dual;
結果:
但是對於SUBSTR()函數千萬要記住一點,它的下標是從1開始的,也就是在進行截取的時候,字元串從1開始作為索引下標,但是即使設置的值是0,也是按照1來處理。
例如:代碼示例:
1 SELECT SUBSTR('helloworldnihao',0,5) FROM dual;
2
3 SELECT SUBSTR('helloworldnihao',1,5) FROM dual;
結果:
範例:要求截取每一位雇員姓名的前三位字元
代碼示例:
1 SELECT ename,SUBSTR(ename,1,3) FROM emp;
結果如下:
範例:要求截取姓名的後三個字母。此範例可以採用兩種做法:
第一種(傳統做法):如果進行截取,那麼首先一定要確認出截取的開始點,所以對於開始點,由於每一個姓名的長度都是不一樣的,所以開始點也是不一樣的。所以採用最好的辦法就是進行計算。就可以使用LENGTH來計算長度。
代碼示例:
1 SELECT ename,SUBSTR(ename,LENGTH(ename)-2) FROM emp;
查詢結果:
SUBSTR()的支持,可以設置負數索引。
代碼示例:
1 SELECT ename,SUBSTR(ename,-3) FROM emp;
實際上只有Oracle資料庫才會支持這種負數的索引設計,其他的任何語言都是不支持。
面試題:請問Oracle中的SUBSTR()函數截取字元串的索引是從1開始還是從0開始?
答案:Oracle資料庫中的字元串的索引都是從1開始的,即使設置的值是0,也會將其自動變為1開始執行。
數值函數
數值函數主要是針對於數字進行處理的,有三個主要的函數:ROUND()、TRUNC()、MOD()。
1.四捨五入操作
語法:
1 數字 ROUND(列| 數字,[保留小數位])如果不設置小數位就表示不保留。
範例:測試四捨五入
代碼示例及解析:
1 SELECT
2
3 ROUND(78915.678932654), 78916,小數點之後的內容直接進行四捨五入
4
5 ROUND(78915.678932654,2), 78915068 保留兩位小數
6
7 ROUND(78915.678932654,-2), 78900,把不足5的數字全部取消了。
8
9 ROUND(78985.678932654,-2), 79000,如果超過了5則進行進位
10
11 ROUND(-15.32) -15
12
13 FROM dual;
結果如下:
2.截取小數,所有的小數都不進位。
語法:
1 數字 TRUNC(列 | 數字[,小數位])
代碼示例:
1 SELECT
2
3 TRUNC(78915.678932654), 78916
4
5 TRUNC(78915.678932654,2), 78915.68
6
7 TRUNC(78915.678932654,-2), 78900
8
9 TRUNC(78985.678932654,-2), 79000
10
11 TRUNC(-15.32) -15
12
13 FROM dual;
14
15
結果如下:
3.求模(求餘數)
語法:
1 數字 MOD(列1 | 數字1,列2 | 數字2)
範例:求模操作
代碼示例:
1 SELECT MOD(10,3) FROM dual;
日期函數(Oracle自己的特色)
日期處理函數主要是進行日期處理,但是整個日期處理過程中會存在一個關鍵詞的問題。如何可以取得當前的日期時間。在Oracle中會提供一個數據偽列。指的是一個列,但是不存在於表中,可是卻可以像列一樣進行數據的查詢。那麼這個偽列就是SYSDATE。
代碼示例:
1 SELECT ename, hiredate, SYSDATE FROM emp;
如果只是單純地想要取得日期,可以使用簡單一些,直接使用dual虛擬表就可以。
代碼示例:
1 SELECT SYSDATE FROM dual;
如果是用具體地時間戳,那麼就可以直接加SYSTIMESTAMP。
代碼示例:
1 SELECT SYSDATE,SYSTIMESTAMP FROM dual;
實際上對於日期時間提供有三種計算模式:
1 日期 + 數字 = 日期(若幹天後地日期) 2 3 日期 – 數字 = 日期(若幹之前地日期) 4 5 日期 – 日期 = 數字 (兩個日期間的天數) 6 7
測試:若幹天後的日期
代碼示例1:
1 SELECT SYSDATE+10 FROM dual;
代碼示例2:
1 SELECT SYSDATE+10, FROM dual;
在進行日期與數字的計算之中,得到的結果都是比較容易理解的。
範例:計算每一位雇員到今天為止的雇佣天數。
代碼示例:
1 SELECT ename,hiredate,SYSDATE-hiredate FROM emp;
通過以上的分析發現,如果現在只是依靠天數實際上是很難得到一個準確的年或者是月,所以為了可以精確的進行計算,在Oracle裡面才提供有日期處理函數,利用這些函數可以避免掉那些閏年或者是閏月的問題。
計算兩個日期間所經歷的月數總和。
語法:
1 數字 MONTHS_BETWEEN(日期1,日期2)
範例:計算每一位雇員到今天為止的雇佣總月數。
代碼示例:
1 SELECT ename,hiredate,MONTHS_BETWEEN(SYSDATE,hiredate) FROM emp;
實際上,現在已經存在有月的數據了,那麼就表示可以準確計算年。
範例:計算每一個雇員到今天為止所雇佣的年限。
代碼示例:
1 SELECT ename,hiredate,TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) FROM emp;
增加若幹月之後的日期。
語法:
1 日期 ADD_MONTHS(日期,月數)
範例:測試ADD_MONTHS()函數。
代碼示例:
1 SELECT ADD_MONTHS(SYSDATE,4) FROM dual;
利用這種方式增加的月可以避免閏年、閏月這兩個問題。
範例:計算所有還差1年滿34年雇佣日期的全部雇員。
代碼示例:
1 SELECT * FROM emp WHERE TRUNC(MONTHS_BETWEEN(SYSDATE, hiredate)/12)=34;
- 計算指定日期所在月的最後一天。
語法:
1 日期 LAST_DAY(日期)
範例1:計算當前日期所在月的最後一天。
代碼示例:
1 SELECT LAST_DAY(SYSDATE) FROM dual;
範例2:查詢出所有在雇佣所在月倒數第二天被雇佣的雇員信息
每一個雇員的雇佣日期都是不一樣的,所以在每一個雇佣日期所在月的倒數第二天也不一樣的。
·首先應該知道每一個雇員雇佣月的最後一天,而後利用“日期 + 數字 = 日期”,計算倒數第二天。
代碼示例:
1 SELECT ename,hiredate, LAST_DAY(hiredate),LAST_DAY(hiredate)-2
2
3 FROM emp
4
5 WHERE LAST_DAY(hiredate)-2=hiredate;
- 計算下一個指定的日期
語法:日期 next_day(日期,一周時間數)
範例:計算下一個周二
代碼示例:
1 SELECT NEXT_DAY(SYSDATE,'星期二') FROM dual;
【瞭解】綜合分析:要求查詢雇員的編號、姓名、雇佣日期,以及每一位雇員到今天為止所雇佣的年數、月數、天數。
假設現在的日期是:2018-07-06
現在WARD他的雇佣日期為:“1981-02-22”,所以它到今天為止的雇佣日期已經被雇佣了:35年、0月,15天。
對於該查詢而言,由於日期的跨度較長。所以要想準確的計算出結果。
代碼示例:
1 SELECT empno,aname,hiredate
2
3 TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) year
4
5 FROM emp;
第二步:計算月
在進行計算年的時候就包含餘數,餘數實際上就是除以12的結果,餘數就是月數。利用MOD()函數求出餘數。
加上TRUNC之後的結果如下:
第三步:計算天數
計算天數的操作只有一個公式:“日期1 – 日期2 = 數字(天數)”,現在就出現了日期的問題上:
日期1:一定是當前日期,肯定是使用SYSDATE偽例。
日期:實際上可以使用MONTHS_BETWEEN()函數求出兩個日期之間的月數。
觀察可以發現,天數裡面計算結果也會有小數點,所以我們加上TRUNC之後,就會只有整數形式的結果。
轉換函數(重點)
就目前而言,在Oracle中的三種數據類型:字元串、數字、日期。所以所謂的轉換函數的實現字元串與日期、數字之間的轉換。
轉換函數一共提供有三種:TO_CHAR()、TO_DATE()、TO_NUMBER()。針對於轉換函數而言,重點的是TO_CHAR()。
1.轉字元串函數,數字或者是日期可以轉換為字元串。
語法:字元串 TO_CHAR(列 | 日期 | 數字,轉換格式)
對於轉換格式而言,主要有兩類格式:
- 日期轉換為字元串:年(yyyy)、月(mm)、日(hh、hh24)、分(mi)、秒(ss)。
- 數字轉換為字元串:任意一位數字(9)、貨幣(L,本地貨幣)。
範例:格式化日期。
代碼格式:
1 SELECT TO_CHAR(SYSDATE,'yyyy-mm-dd'),TO_CHAR(SYSDATE,'yyyy-mm-dd hh24-mi-ss')FROM dual;
在這裡提供了思想:日期要想該改變日期,最終的數據類型就是字元串。如果要這樣子轉換實際上會破壞程式的一致性。
實際上現在可以進一步探索TO_CAHR()好處,它可以實現年月份、月、日的拆分。
範例:查詢出,每個雇員的編號、姓名、雇佣年份。
代碼示例:
1 SELECT * empno,ename,TO_CHAR(hiredate,'yyyy') year FROM emp;
範例:查詢出所有在2月雇佣的雇員信息。
代碼示例:
Oracle中實際上提供有數據類型的自動轉換,如果發現比較的類型不統一,在一定的範圍內是可以轉換的。
TO_CHAR()函數除了可以進行日期的轉換之外,也是支持數字轉換的。所謂的數字轉換往往是針對於數字的可讀性進行一些格式化的操作。
範例:轉換數字
代碼示例:
1 SELECT TO_CHAR(8899,'L999,999,999,999') FROM dual;
2.轉日期函數
如果說現在某一個字元按照“日 - 月 - 年”的格式去編寫。那麼可以自動轉換為日期類型,但是也可以依靠TO_DATE()函數來完成。
語法格式:
1 TO_DATE(字元串,轉換格式)
- 年(yyyy)、月(mm)、日(hh、hh24)、分(mi)、秒(ss)。
範例:實現字元串轉換為日期。
代碼示例:
1 SELECT TO_DATE('1995-05-02','yyyy-mm-dd') FROM dual;
3.轉數字函數
可以將字元串(由字元串所組成),變為數字。
語法格式:
1 數字 TO_NUMBER(字元串)。
範例:驗證轉數字函數
代碼示例:
1 SELECT TO_NUMBER('1') + TO_NUMBER('2') FROM dual;
通用函數(oracle自己的特色)
在Oracle中提供了兩個簡單的數據處理函數:NVL()、DECODE()。並且隨著版本的提升,此兩個函數也衍生出了許多的子函數。
1.處理null
計算出每一個雇員的年薪,包括基本工資和佣金。
代碼示例:
1 SELECT empno,ename,job,(sal+comm)*12 income FROM emp;
現在發現,所有沒有佣金的雇員,現在進行年收入計算的時候,最終的計算結果都是Null ,因為null在進行任何數學計算的時候,結果永遠都是null。而實際上在計算之中,如果發現內容為null,如果是數字則應該使用0來替代,那麼就需要利用我們的NVL()函數來解決此類問題。
語法格式:
1 NVL(列 | null,為空的預設值)如果在列上的內容不是null則使用列的數據,如果為null,則使用預設值。
代碼示例:
1 SELECT empno,ename,job,sal,NVL(comm,0),(sal+NVL(comm,0))*12 income FROM emp;
2.多數值判斷
所謂的多數值判斷,指的是根據不同的結果可以在輸出的時候進行嚴格數據的轉換,假設每一個雇員都有自己的職位。職位現在使用的是英文描述,決定使用更換為中文描述。
代碼示例:
1 SELECT empno,ename,job,DECODE(job,'CLERK','辦事員','SALESMAN','銷售','暫無此信息') FROM emp; 2 3 4 5 SELECT empno,ename,job,DECODE(job,'CLERK','辦事員','SALESMAN','銷售') FROM emp;