Oracle數據庫之六 單行函數

6、單行函數

6.一、認識單行函數

​ 函數就是和 Java 語言之中的方法的功能是同樣的,都是爲了完成某些特定操做的功能支持,而在 Oracle 數據庫裏面也包含了大量的單行函數,這些函數掌握了之後,能夠方便的幫助進行數據庫的相關開發。html

​ 對開發者而言,最爲重要的就是 SQL 語法和單行函數,但是 Oracle 中的單行函數的數量是很是多的。本章只講解使用,後面會講解如何去開發用戶本身的函數(PL/SQL 編程)java

6.1.1 單行函數語法

​ funcation_name(列|表達式[,參數1,參數2,])面試

​ 函數名稱(列 | 表達式 | 數值),並且在Oracle 書中只講解基本的一些單行函數。sql

6.1.2 單行函數分類

  • 字符函數:接收數據返回具體的字符信息
  • 數值函數:對數字進行處理,如:四捨五入
  • 日期函數:直接對日期進行相關操做
  • 轉換函數:日期、字符、數字之間能夠完成互相轉換功能
  • 通用函數:Oracle 子句提供的有特點的函數

6.二、字符函數

  • 必定是以字符數據爲主(字符串)
NO. 函數名稱 描述
1 UPPER(列|字符串) 將字符串的內容所有轉大寫
2 LOWER(列|字符串) 將字符串的內容所有轉小寫
3 INITCAP(列|字符串) 將字符串的開頭首字母大寫
4 REPLACE(列|字符串,新的字符串) 使用新的字符串替換舊的字符串
5 LENGTH(列|字符串) 求出字符串長度
6 SUBSTR(列|字符串,開始點[,長度]) 字符串截取
7 ASCII(字符) 返回與指定字符對應的十進制數字
8 CHR(數字) 給出一個整數,並返回與之對應的字符
9 RPAD(列|字符串,長度,填充字符)<br>LPAD(列|字符串,長度,填充字符) 在左或右填充指定長度字符串
10 LTRIM(字符串) , RTRIM(字符串) 去掉左或右空格
11 TRIM(列|字符串) 去掉左右空格
12 INSTR(列|字符串,要查找的字符串,開始位置,出現位置) 查找一個字符串是否在指定位置上出現
  • 在這裏有一個問題就會出現,在 Oracle 裏面全部的驗證操做必須存在在完整的 SQL 語句之中,因此若是如今只是進行功能驗證,使用的是一張具體的表。
scott 用戶下:
SELECT UPPER('li xing hua') 
FORM emp;
  • 這個時候發現結果被重複顯示了14行,因此如今函數的功能的確是進行了驗證,可是代價過高。若是使用 DISTINCT 能夠消除,那麼若是 emp 表中的數據不少呢?那麼中間處理的數據量就會很大,因此如今就但願有一張表能夠幫助用戶進行驗證,而在 Oracle 裏就提供了一個 dual 的數據表(是虛擬表)。

範例:驗證 UPPER() 和 LOWER() 函數數據庫

SELECT UPPER('li xing hua'),LOWER('MLDN')
FORM dual;

範例:如今查詢出僱員姓名是「smith」的完整信息,可是因爲失誤,沒有考慮到大小寫問題,此時可使用UPPER() 函數將所有內容變爲大寫。編程

SELECT * 
FORM emp
WHERE ename = UPPER('smith');

範例:查詢全部僱員姓名,要求每一個僱員的姓名以首字母大寫的形式出現c#

SELECT ename 原始姓名,INITCAP(ename) 姓名開頭首字母大寫
FORM emp;

範例:查詢全部僱員信息,要求將僱員姓名中全部的字母「A」替換成「_」函數

SELECT ename,REPLACE(ename,'A','_')
FORM emp;

範例:查出姓名長度是5的全部僱員信息學習

SELECT * 
FORM emp
WHERE LENGTH(ename) = 5;

範例:查詢出僱員姓名前三個字母是「JAM」的僱員信息測試

  • 那麼如今要想辦法截取出前三個字符,截取操做就必定要使用 SUBSTR() 函數,要注意的是,SUBSTR() 函數有兩種形式:
    • 從指定位置截取到結尾:SUBSTR(列 | 字符串,截取開始點)
    • 截取部分字符串:SUBSTR(列 | 字符串,截取開始點,截取個數)
SELECT * 
FORM emp
WHERE SUBSTR(ename,1,3) = 'JAM'; 

或者:

SELECT * 
FORM emp
WHERE SUBSTR(ename,0,3) = 'JAM';
  • 注意:在 Oracle 中,下標都是從1開始,若是設置爲0,也會自動將其轉換爲1 。

範例: 查詢全部10部門僱員姓名,但不顯示每一個僱員姓名的前三個字母

SELECT ename 原姓名,SUBSTR(ename,3) 截取以後的姓名 
FORM emp
WHERE deptno = 10;

範例:顯示每一個僱員姓名及姓名的後三個字母

  • 要想截取每一個姓名之中的後三個,首先要解決的問題是開始點,從一個指定的開始點一直截取到結尾,但是每一個僱員的姓名長度是不一樣的,那麼開始點如何肯定呢?

    • 實現一:使用傳統作法,先求得姓名長度,而後減2肯定開始點
    SELECT ename 原始姓名,SUBSTR(ename,LENGTH(ename) - 2) 截取以後的姓名  
    FORM emp
    WHERE deptno = 10;
    • 實現二:除了此類作法以外,也能夠設置開始點爲負數
    SELECT ename 原始姓名,SUBSTR(ename,-3) 截取以後的姓名  
    FORM emp
    WHERE deptno = 10;
  • 如今很明顯使用第二種最方便,這個也屬於 Oracle 的特點,不過須要注意的是:Java 語言的字符串下標仍是從0開始,並且 Java 裏的 substring() 方法是不能設置負數的。

  • **面試題:**請問 Oracle 中的 SUBSTR() 函數的下標開始點是從0仍是1開始?

    ​ 答:能夠設置爲0,也能夠設置爲1,即便使用了0,那麼最終的結果也會將其定義爲1。

範例:返回指定字符的 ASCII 碼

SELECT ASCII('A'),ASCII('L')
FORM dual;

範例:驗證 CHR() 函數,將ASCII 碼變回字符

SELECT CHR(100) FORM dual;

範例:去掉字符串左邊空格 - LTRIM() ,去掉右邊空格 - RTRIM()

SELECT '     MLDN    LiXingHua     ' 原始字符串,LTRIM('    ') 去掉左空格
FORM dual;

SELECT '     MLDN    LiXingHua     ' 原始字符串,RTRIM('    ') 去掉右空格
FORM dual;

範例:去掉左右空格

SELECT '     MLDN    LiXingHua     ' 原始字符串,TRIM('    ') 去掉左右空格
FORM dual;
  • 無論如何取消空格,中間的空格但是沒法消除掉的。

範例:字符串左填充 - LPAD() ,字符串右填充 - RPAD()

SELECT LPAD('MLDN',10,'*') LPAD函數使用,RPAD('MLDN',10,'*') RPAD函數使用,
LPAD(RPAD('MLDN',10,'*'),16,'*') 組合使用 
FORM dual;

範例:字符串查找 - INSTR()

SELECT 
	INSTR('MLDN Java','MLDN') 查找獲得,
	INSTR('MLDN Java','Java') 查找獲得,
	INSTR('MLDN Java','JAVA') 查找不到
FORM dual;
  • 這個函數和 Java 中的 indexOf() 方法功能是相同的。
  • 小結:
    • 字符函數的主要功能是進行字符串數據的操做

6.三、數值函數

No. 函數名稱 描述
1 ROUND(數字[,保留小數]) 對小數進行四捨五入,能夠指定保留位數,若是不指定,則表示將小數點以後的數字所有進行四捨五入
2 TRUNC(數字[,截取位數]) 保留指定位數的小數,若是不指定,則表示不保留小數
3 MOD(數字,數字) 取模

範例:驗證 ROUND() 函數的使用

SELECT 
    ROUND(789.652) 不保留小數,
	ROUND(789.652,2) 不保留小數,
	ROUND(789.652,-1) 不保留小數,
FROM dual;

範例:列出每一個僱員的一些基本信息和日工資狀況

  • 對於日工資的計算能夠採用30天爲基礎,確定會有小數,就保留2位
SELECT empno,ename,job,hiredate,sal,ROUND(sal/30,2) 日薪金
FROM emp;
  • ROUND() 函數的功能是小數進位,而 TRUNC() 的功能是不進位。

範例:驗證 TRUNC() 函數的使用

SELECT 
    TRUNC(789.652) 截取小數,
	TRUNC(789.652,2) 截取2位小數,
	TRUNC(789.652,-2) 取整
FROM dual;

範例:MOD() 函數驗證,模就是取餘

SELECT MOD(10,3) FROM dual;

6.四、日期函數

  • 若是如今要想進行日期的操做,那必定會存在一個前提,必須知道當前日期
  • 取得當前的系統時間,能夠直接利用 SYSDATE 僞列取得當前日期時間。所謂僞列指的是否是表中的列,可是有能夠直接使用的列。
SELECT empno,ename,SYSDATE FROM emp;
SELECT SYSDATE FROM dual;
  • 在默認狀況下顯示的內容,只包含了年、月、日三個內容,若是要顯示更多內容,就必須修改語言環境。
  • 修改日期顯示格式:
    • 運行 - sqlplus/nolog - conn c##scott/tiger
    • 輸入如下代碼
ALTER SESSION SET NLS_DATE_FORMAT = 'yyyy-mm-dd hh24:mi:ss';
SELECT SYSDATE FROM dual;
  • 更改的日期顯示格式在關閉窗口從新打開後就會還原了

  • 除了取得系統時間的操做以外,在 Oracle 中也有以下的三個日期操做公式:

    • 日期 - 數字 = 日期, 表示若干天前的日期
    • 日期 + 數字 = 日期, 表示若干天后的日期
    • 日期 - 日期 = 數字(天數),表示兩個日期的天數的間隔
  • 但是絕對不會存在 「日期 + 日期」 的計算,下面爲其驗證。

SELECT 
    SYSDATE+3 三天以後的日期,
	SYSDATE-3 三天以前的日期
FROM dual;

範例:查詢出每一個僱員的到今天爲止的僱傭天數,以及十天前天天僱員的僱傭天數

SELECT empno 僱員編號, ename 僱員姓名, 
	SYSDATE-hiredate 僱傭天數, 
	(SYSDATE-10)-hiredate 10天前僱傭天數
FROM emp;
  • 結果有小數點,能夠用 TRUNC() 截取小數點
SELECT empno 僱員編號, ename 僱員姓名, 
	TRUNC(SYSDATE-hiredate) 僱傭天數, 
	TRUNC((SYSDATE-10)-hiredate) 10天前僱傭天數
FROM emp;
  • 以上只是針對於當前時間的操做,對於 Oracle 而言,也提供相應的日期函數,之因此使用日期函數,主要是避免閏年問題,或者是一個月有28,29,30,31天的問題,經過日期函數的計算取得的日期時間是最準確的。
No. 函數名稱 描述
1 ADD_MONTHS(日期,數字) 在指定的日期上加入指定的月數,求出新的日期
2 MONTHS_BETWEEN(日期1,日期2) 求出兩個日期間的僱傭月數
3 NEXT_DAY(日期,星期數) 求出下一個星期幾的具體日期
4 LAST_DAY(日期) 求出指定日期所在月的最後一天日期
5 EXTRACT(格式 FROM 數據) 日期時間分隔,或計算給定兩個日期的間隔

範例:驗證 ADD_MONTHS() 函數

  • 使用 ADD_MONTHS() 函數的主要功能是在一個指定日期上增長若干個月以後求得的新日期。
SELECT SYSDATE,
	ADD_MONTHS(SYSDATE,3) 三個月以後的日期,
	ADD_MONTHS(SYSDATE,-3) 三個月以前的日期,
	ADD_MONTHS(SYSDATE,60) 六十個月以後的日期,
FROM dual;

範例:要求顯示全部僱員在被僱傭三個月以後的日期

SELECT empno,ename,job,sal,hiredate,ADD_MONTHS(hiredate,3)
FROM emp;

範例:驗證 NEXT_DAY() 函數

  • 主要是求出下一個指定的日期數,若是說如今的日期是‘2019年08月30日 星期五’ ,那麼若是如今想要知道下一個‘星期一’ 或是 ‘星期日’ 的具體日期,則可使用 NEXT_DAY() 函數。
SELECT 
	SYSDATE,
	NEXT_DAY(SYSDATE,'星期日') 下一個星期日,
	NEXT_DAY(SYSDATE,'星期一') 下一個星期一
FROM dual;

範例:LAST_DAY() 函數驗證,求當月的最後一天

SELECT SYSDATE,
	LAST_DAY(SYSDATE)
FROM dual;

範例:查詢全部是在其僱傭所在月的倒數第三天被公司僱傭的完整僱傭信息

  • 每一位僱員都有本身的僱傭日期,那麼如今要查詢出,你僱傭日期所在月倒數第三天僱傭的人,首先須要知道的是每一個僱員僱傭所在月的最後一天。
SELECT empno,ename,job,hiredate,LAST_DAY(hiredate) 
FROM emp
WHERE LAST_DAY(hiredate)-2=hiredate;

範例:MONTHS_BETWEEN() 函數的驗證:查詢出每一個僱員的編號、姓名、僱員傭日期,僱傭的月數及年份

  • MONTHS_BETWEEN() 函數的功能是取得兩個日期時間的月份間隔
SELECT 
	empno 僱員編號, ename 僱員姓名, hiredate 僱傭日期,
	TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)) 僱傭總月數,
	TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) 僱傭總年數
FROM emp;

範例:查詢出每一個僱員的編號、姓名、僱傭日期、已僱傭的年數、月數、天數

  • 對於本程序而言,必定是分步計算,並且有必定的難度,由於要操做的是準確性。
  • 例如,今天的日期是 2019-09-01日,而 BLAKE 的僱傭日期是 1981-05-01,那麼這位僱員到今天爲止被僱傭了38年、4個月、0天。
  • 步驟一:求出年,年只須要依靠月就能夠計算出來。
SELECT 
	empno 僱員編號, ename 僱員姓名, hiredate 僱傭日期,
	TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) 僱傭總年數
FROM emp;
  • 步驟二:求出月,計算年的時候存在小數,那麼這裏面的數據就是月,只須要求模便可獲得。
SELECT 
	empno 僱員編號, ename 僱員姓名, hiredate 僱傭日期,
	TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) 已僱傭年數,
	TRUNC(MOD(MONTHS_BETWEEN(SYSDATE,hiredate),12)) 已僱傭月數
FROM emp;
  • 步驟三:是針對於天的計算,由於如今已經計算出了年和月,因此天應該刨去年和月的數字信息。那麼如今的問題是,若是要想計算天數惟一知道的公式就是 「日期1 - 日期2」,那麼日期1 必定使用的是 SYSDATE ,而日期2(應該去掉年和月),能夠利用 ADD_MONTHS() 函數實現此功能。
SELECT 
	empno 僱員編號, ename 僱員姓名, hiredate 僱傭日期,
	TRUNC(MONTHS_BETWEEN(SYSDATE,hiredate)/12) 已僱傭年數,
	TRUNC(MOD(MONTHS_BETWEEN(SYSDATE,hiredate),12)) 已僱傭月數,
	TRUNC(SYSDATE - ADD_MONTHS(hiredate,MONTHS_BETWEEN(SYSDATE,hiredate))) 已僱傭天數
FROM emp;

範例:EXTRACT() 函數

  • 在 Oracle 9i 以後增長了一個 EXTRACT() 函數,此函數的主要功能是能夠從一個日期時間(DATE)或者是時間間隔(INTERVAL)中截取出特定的部分,此函數使用語法以下:
EXTRACT
    ([YEAR | MONTH | DAY | HOUR | MINUTE | SECOND]
	| [TIMEZONE_HOUR | TIMEZONE_MINUTE]
	| [TIMEZONE_REGION | TIMEZONE_ABBR]
FROM 
     [日期(date_value) | 時間間隔(interval_value)]);

範例:從日期時間之中取出年、月、日數據

SELECT 
	EXTRACT(YEAR FROM DATE '2001-09-19') years,
	EXTRACT(MONTH FROM DATE '2001-09-19') months,
	EXTRACT(DAY FROM DATE '2001-09-19') days
FROM dual;
  • 如今是經過一個日期的字符串完成,那麼也能夠利用當前日期完成。SYSDATE、SYSTIMESTAMP(時間戳)。
SELECT SYSDATE,SYSTIMESTAMP
FROM dual;

範例:從時間戳之中取出年、月、日、時、分、秒

SELECT
	EXTRACT(YEAR FROM SYSTIMESTAMP) years,
	EXTRACT(MONTH FROM SYSTIMESTAMP) months,
	EXTRACT(DAY FROM SYSTIMESTAMP) days,
	EXTRACT(HOUR FROM SYSTIMESTAMP) hours,
	EXTRACT(MINUTE FROM SYSTIMESTAMP) minutes,
	EXTRACT(SECOND FROM SYSTIMESTAMP) seconds
FROM dual;
  • 除了以上功能以外,主要功能是取得時間間隔,可是在此處須要使用到一個轉換函數:TO_TIMESTAMP() ,能夠將字符串變爲時間戳,並且此時的內容須要使用到部分子查詢功能,因此此處只爲作個演示。

範例:取得兩個日期之間的間隔

SELECT 
	EXTRACT(DAY FROM TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss')
		- TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) days
FROM dual;

範例:取得兩個日期時間之間間隔的天、時、分、秒

SELECT 
	EXTRACT(DAY FROM datetime_one - datetime_two) days,
	EXTRACT(HOUR FROM datetime_one - datetime_two) hours,
	EXTRACT(MINUTE FROM datetime_one - datetime_two) minutes,
	EXTRACT(SECOND FROM datetime_one - datetime_two) seconds
FROM (
	SELECT TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss') datetime_one,
		TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss') datetime_two
	FROM dual);
  • 若是以爲比較麻煩,也能夠不使用子查詢,按原來的方法寫代碼就以下:
SELECT 
	EXTRACT(DAY FROM TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss')
		- TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) days,
	EXTRACT(HOUR FROM TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss')
		- TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) hours,
	EXTRACT(MINUTE FROM TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss')
		- TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) minutes,
	EXTRACT(SECOND FROM TO_TIMESTAMP('1982-08-13 12:17:57','yyyy-mm-dd hh24:mi:ss')
		- TO_TIMESTAMP('1981-09-27 09:08:33','yyyy-mm-dd hh24:mi:ss')) seconds
FROM dual;
  • 這樣看來,第二種方式就是最差的一種方式了,不推薦使用。

6.五、轉換函數

  • 在數據庫之中主要使用的數據類型:字符、數字、日期(時間戳),那麼這三種數據類型之間就須要實現轉換操做,這就屬於轉換函數的功能。
No. 函數名稱 描述
1 TO_CHAR(日期|數字|列, 轉換格式) 將指定的數據按照指定的格式變爲字符串型
2 TO_DATE(字符串|列, 轉換格式) 將指定的字符串按照指定的格式變爲DATE型
3 TO_NUMBER(字符串|列) 將指定的數據類型變爲數字型

6.5.1 TO_CHAR() 函數

  • 在默認的狀況下,若是查詢一個日期,則日期默認的顯示格式爲「31-1月-12」,而這樣的日期顯示效果確定不如常見的「2012-01-31」 讓人看起來習慣,因此此時就能夠經過TO_CHAR() 函數對這個顯示的日期數據進行格式化(格式化以後的數據是字符串),可是若是要完成這種格式化,則首先要熟悉一下格式化日期的替代標記。

**日期格式化標記: **

No. 轉換格式 描述
1 YYYY 完整的年份數字表示,年有四位,因此使用4個Y
2 Y,YYY 帶逗號的年
3 YYY 年的後三位
4 YY 年的後兩位
5 Y 年的最後一位
6 YEAR 年份的文字表示,直接表示四位的年
7 MONTH 月份的文字表示,直接表示兩位的月
8 MM 用兩位數字來表示月份,月有兩位,使用兩個M
9 DAY 天數的文字表示
10 DDD 表示一年裏的天數(001~366)
11 DD 表示一月裏的天數(01~31)
12 D 表示一週裏的天數(1~7)
13 DY 用文字表示星期幾
14 WW 表示一年裏的週數
15 W 表示一月裏的週數
16 HH 表示12小時制,小時是兩位數字,使用兩個H
17 HH24 表示24小時制
18 MI 表示分鐘
19 SS 表示秒,秒是兩位數字,使用兩個S
20 SSSSS 午夜以後的秒數字表示(0~86399)
21 AM|PM (A.M | P.M) 表示上午或下午
22 FM 去掉查詢後的前導0,該標記用於時間模板的後綴
  • 在 TO_CHAR() 函數裏面,須要兩個參數:日期數據,轉換格式

範例:格式化日期時間

SELECT SYSDATE 當前系統時間,
	TO_CHAR(SYSDATE,'YYYY-MM-DD') 格式化日期,
	TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS') 格式化日期時間,
	TO_CHAR(SYSDATE,'FMYYYY-MM-DD HH24:MI:SS') 去掉前導0的時間
FROM dual;
  • 注意:在開發中必定別取消前導0

範例:使用其餘方式格式化年、月、日

  • 除了使用標記(是一種習慣,java.text.SimpleDateFormat),也可使用單詞表示
SELECT SYSDATE 當前系統時間,
	TO_CHAR(SYSDATE,'YEAR-MONTH-DAY') 格式化日期
FROM dual;

或者:

SELECT SYSDATE 當前系統時間,
	TO_CHAR(SYSDATE,'YEAR-MONTH-DY') 格式化日期
FROM dual;

範例:查詢出全部在每一年2月份僱傭的僱員信息

SELECT * 
FROM emp 
WHERE TO_CHAR(hiredate,'MM') = 2;

或者:

SELECT * 
FROM emp 
WHERE TO_CHAR(hiredate,'MM') = '02';

範例:將每一個僱員的僱傭日期進行格式化顯示,要求全部的僱傭日期能夠按照「年-月-日」的形式顯示,也可將僱傭的年、月、日拆開分別顯示

SELECT empno,ename,job,hiredate,
	TO_CHAR(hiredate,'YYYY-MM-DD') 格式化僱傭日期,
	TO_CHAR(hiredate,'YYYY') 年,
	TO_CHAR(hiredate,'MM') 月,
	TO_CHAR(hiredate,'DD') 日
FROM emp;
  • TO_CHAR() 函數的最爲重要的功能是能夠將數字格式化,例如:2389042809,若是是有經驗的財務人員會按照三位一分:2,389,042,809 ,而要想按照此方法處理數字,就必須格式化。

數字格式化標記

No. 轉換格式 描述
1 9 表示一位數字
2 0 表示前導0
3 $ 將貨幣的符號信息顯示爲美圓符號
4 L 根據語言環境不一樣,自動選擇貨幣符號
5 . 顯示小數點
6 , 顯示千位符

範例:格式化數字顯示

SELECT
	TO_CHAR(987654321.789,'999,999,999,999.9999') 格式化數字,
	TO_CHAR(987654321.789,'000,000,000,000.0000') 格式化數字
FROM dual;
  • 除了直接對數字格式化,也能夠進行貨幣的顯示
SELECT
	TO_CHAR(987654321.789,'L999,999,999,999.9999') 顯示貨幣,
	TO_CHAR(987654321.789,'$999,999,999,999.9999') 顯示美圓
FROM dual;
  • 在開發之中,TO_CHAR() 函數的做用仍是很是明顯的!建議掌握!

6.5.2 TO_DATE() 函數

  • 這個函數主要是將字符串變爲日期型數據,而改變的過程裏面依然須要以前 TO_CHAR() 函數出現的相關標記。

範例:轉換時間顯示

SELECT 
	TO_DATE('1979-09-19','YYYY-MM-DD')
FROM dual;
  • 在以前講解日期函數時使用了一個 TO_TIMESTAMP() 函數,這個函數是將字符串變爲時間戳。

範例:時間戳轉換

SELECT
	TO_TIMESTAMP('1981-09-27 18:07:10','YYYY-MM-DD HH24:MI:SS') datetime
FROM dual;

6.5.3 TO_NUMBER() 函數

  • 做用是將字符串變爲數字

範例:將字符串變爲數字

SELECT
	TO_NUMBER('09') + TO_NUMBER('19') 加法操做,
	TO_NUMBER('09') * TO_NUMBER('19') 乘法操做
FROM dual;
  • 可是在以前強調過,Oracle 裏面支持數據類型的自動轉型操做,上面的代碼也可寫爲
SELECT '09' + '19' 加法操做,
	'09' * '19' 乘法操做
FROM dual;

6.六、通用函數

  • 這些函數是 Oracle 數據庫的特點,對於這些函數了解有必定的好處。
No. 函數名稱 描述
1 NVL(數字|列 , 默認值) 若是顯示的數字是null的話,則使用默認數值表示
2 NVL2(數字|列,返回結果一(不爲空顯示),返回結果二(爲空顯示)) 判斷指定的列是不是null,若是不爲null則返回結果一,爲空則返回結果二
3 NULLIF(表達式一,表達式二) 比較表達式一和表達式二的結果是否相等,若是相等返回NULL,若是不相等返回表達式一
4 DECODE(列|值,判斷值1,顯示結果1,判斷值2,顯示結果2,...,默認值) 多值判斷,若是某一個列(或一個值)與判斷值相同,則使用指定的顯示結果輸出,若是沒有知足條件,在顯示默認值
5 CASE 列|數值 WHEN 表達式1 THEN 顯示結果1 ... ELSE 表達式N ... END 用於實現多條件判斷,在WHEN以後編寫條件,而在THEN以後編寫條件知足的顯示操做,若是都不知足則使用ELSE 中的表達式處理
6 COALESCE(表達式1,表達式2,...表達式n) 將表達式逐個判斷,若是表達式1的內容是null,則顯示錶達式2,若是表達式2的內容是null,則顯示錶達式3,依次類推,若是表達式n的結果仍是null,則返回null
  • 對於通用函數而言,只有兩個核心函數:NVL() , DECODE()

6.6.1 使用 NVL() 函數處理 null

  • 在數據庫之中,null 是沒法進行計算的,即,在一個數學計算之中若是存在了 null,則最後的結果也確定是 null

範例:查詢出每一個僱員的編號、姓名、職位、僱傭日期、年薪

  • 對於年薪最準確的作法是應該計算 「sal + comm」,但是這個時候 comm 列上是存在了 null 數據的
SELECT empno,ename,job,hiredate,(sal+comm)*12 年薪,sal,comm
FROM emp;
  • 由於 comm 上的內容有的是 null,而如今發現,只要是 comm 爲 null 的計算,最終的結果就是 null ,因此在這種狀況下須要針對於 null 進行處理,確定將 null 變爲0才合適

範例:驗證 NVL()

SELECT NVL(null,0),NVL(3,0) 
FROM dual;
  • 這個時候發現若是爲 null,那麼就將其變爲了0,若是不是 null,就繼續使用指定的數值
SELECT empno,ename,job,hiredate,(sal+NVL(comm,0))*12 年薪,sal,comm
FROM emp;

6.6.2 NVL2() 函數

  • NVL2() 函數是在 Oracle 9i 以後增長的一個新的功能函數,相比較 NVL() 函數,NVL2() 函數能夠同時對爲 null 或不爲 null 進行分別判斷並返回不一樣的結果

範例:查詢每一個僱員的編號、姓名、年薪(sal + comm)、基本工資、獎金

SELECT empno,ename,job,hiredate,NVL2(comm,sal+comm,sal),sal,comm
FROM emp;

6.6.3 NULLIF() 函數

  • NULLIF(表達式一,表達式二) 函數的主要功能是判斷兩個表達式的結果是否相等,若是相等則返回 NULL ,不相等則返回表達式一

範例:驗證 NULLIF() 函數

SELECT NULLIF(1,1),NULLIF(1,2)
FROM dual;

範例:查詢僱員編號、姓名、職位,比較姓名和職位的長度

SELECT empno,ename,job,LENGTH(ename),LENGTH(job),NULLIF(LENGTH(ename),LENGTH(job)) nullif
FROM emp;

6.6.4 DECODE() 函數

  • DECODE() 函數是 Oracle 中最有特點的一個函數,DECODE() 函數相似於程序中的 if...else if...else ,可是判斷的內容都是一個具體的值,語法以下:

    DECODE(列|表達式, 值1, 輸出結果, 值2, 輸出結果, ..., 默認值)

範例:測試DECODE() 函數

SELECT 
	DECODE(2,1,'內容爲一',2,'內容爲二'),
	DECODE(2,1,'內容爲一','沒有條件知足')
FROM dual;

範例:如今僱員表中的工做有如下幾種:CLERK:業務員, SALESMAN:銷售人員, MANAGER:經理, ANALYST:分析員, PRESIDENT:總裁 ,要求查詢僱員的姓名、職位、基本工資等信息,可是要求將全部的職位信息都替換爲中文顯示。

SELECT ename,sal,
DECODE(job,
	'CLERK','業務員',
	'SALESMAN','銷售人員',
	'MANAGER','經理',
	'ANALYST','分析員',
	'PRESIDENT','總裁') job
FROM emp;
  • 可是須要注意的是,若是使用 DECODE() 函數判斷,那麼全部的內容都要判斷,若是隻判斷部份內容,其它內容就會顯示 null

6.6.5 CASE 表達式

  • CASE 表達式是在 Oracle 9i 引入的,功能與DECODE() 有些相似,都是執行多條件判斷。不過嚴格來說,CASE表達式自己並不屬於一種函數的範疇,它的主要功能是針對於給定的列或者字段進行依次判斷,在 WHERE 中編寫判斷語句,而在 THEN 中編寫處理語句,最後若是都不知足則使用 ELSE 進行處理。

範例:顯示每一個僱員的工資、姓名、職位,同時顯示新的工資(新的工資標準:辦事員增加10%,銷售人員增加20%,經理增加30%,其餘職位的人增加50%)

SELECT ename,sal,
	CASE job WHEN 'CLERK' THEN sal * 1.1
		WHEN 'SALESMAN' THEN sal * 1.2
		WHEN 'MANAGER' THEN sal * 1.3
	ELSE sal * 1.5
	END 新工資
FROM emp;

6.6.6 COALESCE() 函數

  • COALESCE(表達式1, 表達式2, 表達式3,...表達式n) 函數的主要功能是對 null 進行操做,採用依次判斷表達式的方式完成,若是表達式1爲 null,則顯示錶達式2的內容,若是表達式2的內容爲 null,則顯示錶達式3的內容,依次類推,判斷到最後若是仍是null,則最終的顯示結果就是 null 。

範例:驗證 COALESCE() 函數

SELECT ename,sal,comm,COALESCE(comm,100,2000),
	COALESCE(comm,null,null)
FROM emp;
  • 小結:
    • 這些通用函數都具有一些邏輯性的操做在裏面,在之後進行程序編寫時仍是會使用到的。
    • NVL() 和 DECODE() 是通用函數的基礎,其餘函數都在此函數之上進行功能擴充。

說明:本學習資料是根據李興華的Oracle開發實戰經典整理

原文出處:https://www.cnblogs.com/duncan1863/p/11445474.html

相關文章
相關標籤/搜索