前邊咱們講解了一些經常使用的函數,這些函數不是在各個主流數據庫系統中有着相同的名稱和用法,就是在各個主流數據庫系統中有等價的實現,這些函數能夠基本知足咱們大部分需求。不過在各個主流數據庫系統還提供了一些自身獨有的函數,這些函數在其餘的數據庫系統中通常都沒有等價的實現,使用這些函數之後會給系統的跨數據庫移植帶來必定的麻煩,不過若是系統對跨數據庫移植沒有要求的話,那麼使用這些函數不只能提升開發速度,並且可以更好發揮數據庫系統的性能,因此瞭解它們仍是很是有必要的,所以這裏咱們專門安排一節來介紹這些函數。java
MYSQL中的獨有函數算法
IF()函數數據庫
使用CASE函數能夠實現很是複雜的邏輯判斷,但是若只是實現「若是符合條件則返回A,不然返回B」這樣簡單的判斷邏輯的話,使用CASE函數就過於繁瑣,以下:express
CASE WHEN condition THENA ELSE B END
MYSQL提供了IF()函數用於簡化這種邏輯判斷,其語法格式以下:服務器
IF(expr1,expr2,expr3)
若是expr1 爲真(expr1 <> 0 以及expr1<>NULL),那麼IF()返回expr2,不然返回expr3。IF()返回一個數字或字符串,這取決於它被使用的語境。app
這裏使用IF()函數來判斷一我的的體重是否太胖,而若是體重大於50則認爲太胖,不然認爲正常:函數
SELECT FName,FWeight,IF(FWeight>50,"太胖","正常") AS ISTooFat FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:性能
FName FWeight ISTooFat Tom 56.67 太胖 Jim 36.17 正常 Lily 40.33 正常 Kelly 46.23 正常 Sam 48.68 正常 Kerry 66.67 太胖 Smith 51.28 太胖 BillGates 60.32 太胖
CONV()函數用於對數字進行進制轉換,好比將十進制的26轉換爲2進制顯示,其參數格式以下:加密
CONV(N,from_base,to_base)
將數字N從from_base進制轉換到to_base進制,並以字符串表示形式返回。from_base和to_base的最小值爲2,最大值爲36。若是to_base是一個負值,N 將被看做爲是一個有符號數字。不然,N 被視爲是無符號的。spa
下面的SQL語句用於將十進制的26轉換爲2進制顯示、將十六進制的7D轉換爲八進制顯示:
SELECT CONV("26",10,2), CONV(26,10,2),CONV("7D",16,8)
能夠看到數字N既能夠爲字符串也能夠爲整數,若是爲整數則它被解釋爲十進制數字。
執行完畢咱們就能在輸出結果中看到下面的執行結果:
CONV("26",10,2) CONV(26,10,2) CONV("7D",16,8) 11010 11010 175
下面的SQL語句用來將每一個人的體重四捨五入爲整數,而後以二進制的形式顯示它們:
SELECT FWeight,Round(FWeight),CONV(Round(FWeight),10,2) FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FWeight Round(FWeight) CONV(Round(FWeight),10,2) 56.67 57 111001 36.17 36 100100 40.33 40 101000 46.23 46 101110 48.68 49 110001 66.67 67 1000011 51.28 51 110011 60.32 60 111100
在平常系統開發過程當中,咱們最常進行的進制轉換是將十進制的整數轉換爲十六進制顯示,若是使用CONV()函數來進行轉換的話比較麻煩,爲此MYSQL提供了簡化調用的函數BIN(N)、OCT(N)、HEX(N)它們分別用於返回N的字符串表示的二進制、八進制值和十六進制形式。下面的SQL語句將每一個人的體重四捨五入爲整數,而後以二進制、八進制值和十六進制的形式顯示它們:
SELECT FWeight,Round(FWeight),BIN(Round(FWeight)) as b,OCT(Round(FWeight)) as o,HEX(Round(FWeight)) as h FROM T_Person 。在MYSQL中提供了LPAD()、RPAD()函數用於對字符串進行左填充和右填充,其參數格式以下: ```java LPAD(str,len,padstr) RPAD(str,len,padstr)
用字符串padstr 對str 進行左(右)邊填補直至它的長度達到len個字符長度,而後返回str。若是str的長度長於len",那麼它將被截除到len 個字符。
下面的SQL語句分別將每一個人的姓名用星號左填充和右填充到5個字符:
SELECT FName,LPAD(FName,5,"*"),RPAD(FName,5,"*") FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FName LPAD(FName,5,"*") RPAD(FName,5,"*") Tom **Tom Tom** Jim **Jim Jim** Lily *Lily Lily* Kelly Kelly Kelly Sam **Sam Sam** Kerry Kerry Kerry Smith Smith Smith BillGates BillG BillG
REPEAT()函數用來獲得一個子字符串重複了若干次所組成的字符串,其參數格式以下:
REPEAT(str,count)
參數str爲子字符串,而count爲重複次數。
下面的SQL語句用於獲得一個由5個星號以及一個由3個「OK」組成的字符串:
```java
SELECT REPEAT("*",5), REPEAT("OK",3)
執行完畢咱們就能在輸出結果中看到下面的執行結果:
REPEAT("*",5) REPEAT("OK",3)
* OKOKOK
MYSQL中提供了一個簡化REPEAT()的函數SPACE(N),它用來獲得一個有N 空格字符組成的字符串,能夠看作是REPEAT(" ",N)的等價形式。
REVERSE()函數用來將一個字符串的順序顛倒,下面的SQL語句將全部人員的姓名進行了顛倒:
SELECT FName, REVERSE(FName) FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FName REVERSE(FName) Tom moT Jim miJ Lily yliL Kelly ylleK Sam maS Kerry yrreK Smith htimS BillGates setaGlliB
使用CASE函數能夠完成「將1翻譯成VIP客戶,將2翻譯成高級客戶,將3翻譯成普通客戶」這樣的任務,可是使用起來比較麻煩,MYSQL中提供了幾個字符串集合操做函數,分別是ELT()、FIELD()和FIND_IN_SET(),它們將「VIP客戶」、「高級客戶」、「普通客戶」這樣的匹配目標字符串看成集合處理,而將「一、二、3」這樣的數字當成待匹配項。
首先來看ELT()函數,它的參數格式以下:
ELT(N,str1,str2,str3,...)
若是N = 1,返回str1,若是N = 2,返回str2,等等。若是N 小於1 或大於參數的數量,返回NULL。下面的SQL演示了ELT()函數的使用:
SELECT ELT(2, "ej", "Heja", "hej", "foo"),ELT(4, "ej", "Heja", "hej", "foo")
執行完畢咱們就能在輸出結果中看到下面的執行結果:
ELT(2, "ej", "Heja", "hej", "foo") ELT(4, "ej", "Heja", "hej", "foo") Heja foo
ELT()函數在製做報表的時候很是有用。好比表T_Customer中的FLevel字段是整數類型,它記錄了客戶的級別,若是爲1則是VIP客戶,若是爲2則是高級客戶,若是爲3則是普通客戶,在製做報表的時候顯然不該該把一、二、3這樣的數字顯示到報表中,而應該顯示相應的文字,這裏就可使用ELT()函數進行處理,SQL語句以下:
SELECT FName,ELT(FLevel, "VIP客戶", "高級客戶", "普通客戶") FROM T_Customer
與ELT()函數正好相反,FIELD()函數用於計算字符串在一個字符串集合中的位置,它能夠看作是ELT()的反函數。FIELD()函數的參數格式以下:
FIELD(str,str1,str2,str3,...)
返回str在列表str1, str2, str3, ... 中的索引。若是沒有發現匹配項,則返回0。下面的SQL演示了FIELD ()函數的使用:
SELECT FIELD("vip","normal","member","vip") as f1,FIELD("ej", "Hej", "ej", "Heja", "hej", "foo") as f2
執行完畢咱們就能在輸出結果中看到下面的執行結果:
f1 f2 3 2
在數據庫中有時存儲的是字符串,有的狀況下須要將字符串轉換成整數,方便後續系統的處理,這時就可使用CASE()函數,可是若是是在MYSQL中,則使用FIELD()函數更方便。假設客戶信息表T_Customer中的FCustomerTypeName保存的是「VIP」、「會員」、「普通客戶」這樣的文本信息,咱們可使用下面的SQL語句將這些文本信息轉換爲整數來表示:
SELECT FName,FIELD(FCustomerTypeName, "VIP", "會員", "普通客戶") FROM T_Customer
FIELD()函數將中的參數個數是不肯定的,可是在使用的時候參數的個數又是肯定,是不能在運行時動態改變的。有時待匹配的字符串集合也是不肯定的,這時就沒法使用FIELD()函數函數了,MYSQL中提供了FIND_IN_SET()函數,它用一個分隔符分割的字符串作爲待匹配字符串集合,它的參數格式以下:
FIND_IN_SET(str,strlist)
若是字符串str 在由N 個子串組成的列表strlist 中,返回它在strlist中的索引次序(從1開始計數)。一個字符串列表是由經過字符「,」 分隔的多個子串組成。若是str 在不strlist 中或者若是strlist 是一個空串,返回值爲 0。若是任何一個參數爲NULL,返回值也是NULL。若是第一個參數包含一個「,」,這個函數將拋出錯誤信息。下面的SQL演示了FIELD ()函數的使用:
SELECT FIND_IN_SET("b","a,b,c,d") as f1,FIND_IN_SET("d","a,b,c,d") as f2,FIND_IN_SET("w","a,b,c,d") as f3
執行完畢咱們就能在輸出結果中看到下面的執行結果:
f1 f2 f3 2 4 0
MYSQL中的GREATEST()函數和LEAST()函數用於計算一個集合中的最大和最小值,它們的參數個數都是不定的,也就是它們能夠對多個值進行比較。使用演示以下:
SELECT GREATEST(2,7,1,8,30,4,3,99,2,222,12),LEAST(2,7,1,8,30,4,3,99,2,222,12)
執行完畢咱們就能在輸出結果中看到下面的執行結果:
GREATEST(2,7,1,8,30,4,3,99,2,222,12) LEAST(2,7,1,8,30,4,3,99,2,222,12) 222 1
DATABASE()函數返回當前數據庫名;VERSION()函數以一個字符串形式返回MySQL服務器的版本;USER()函數(這個函數還有SYSTEM_USER、SESSION_USER兩個別名)返回當前MySQL 用戶名。下面的SQL語句演示了這幾個函數的使用:
SELECT DATABASE(),VERSION(),USER()
執行完畢咱們就能在輸出結果中看到下面的執行結果:
DATABASE() VERSION() USER() demo 5.0.27-community-nt yzk@192.168.88.2
ENCODE(str,pass_str)函數使用pass_str 作爲密鑰加密str,函數的返回結果是一個與string 同樣長的二進制字符。若是但願將它保存到一個列中,須要使用BLOB列類型。
與ENCODE()函數相反,DECODE()函數使用pass_str 做爲密鑰解密經ENCODE加密後的字符串crypt_str。
下面的SQL語句演示了這兩個函數的使用:
SELECT FName,Length(ENCODE(FName,"aha")),DECODE(ENCODE(FName,"aha"),"aha") FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FName Length(ENCODE(FName,"aha")) DECODE(ENCODE(FName,"aha"),"aha") Tom 3 Tom Jim 3 Jim Lily 4 Lily Kelly 5 Kelly Sam 3 Sam Kerry 5 Kerry Smith 5 Smith BillGates 9 BillGates
除了加解密函數,MYSQL中還提供了對摘要算法的支持,MD5(string)、SHA1(string)兩個函數就是分別用來使用MD5算法和SHA1算法來進行字符串的摘要計算的函數,下面的SQL語句用來計算每一個人的姓名的MD5摘要和SHA1摘要:
SELECT FName,MD5(FName),SHA1(FName) FROM T_Person
使用UUID算法來生成一個惟一的字符串序列被愈來愈多的開發者所使用,MYSQL中也提供了對UUID算法的支持,UUID()函數就是用來生成一個UUID字符串的,使用方法以下:
SELECT UUID(),UUID()
執行完畢咱們就能在輸出結果中看到下面的執行結果(因爲UUID算法生成的字符串是全局惟一的,因此你的運行結果會與這裏顯示的不一樣):
UUID() UUID() d7495ecd-1863-102b-9b74-218a53021251 d7495ef7-1863-102b-9b74-218a53021251
MSSQLServer中的獨有函數
PATINDEX()函數
MSSQLServer的CHARINDEX()函數用來計算字符串中指定表達式的開始位置,它是一種肯定值的匹配,有時咱們須要按照必定模式進行匹配,好比「計算字符串中第一個長度爲2而且第二個字符爲m的子字符串的位置」,這時使用CHARINDEX()函數就不湊效了。
MSSQLServer中PATINDEX()函數就是用來進行這種模式字串匹配的,其參數格式以下:
PATINDEX ( "%pattern%" , expression )
它返回指定表達式中模式"%pattern%"第一次出現的起始位置;若是在所有有效的文本和字符數據類型中沒有找到該模式,則返回零。在模式中可使用通配符。
下面的SQL語句用來查找每一個人的姓名中第一個長度爲2而且第二個字符爲m的子字符串的位置:
SELECT FName,PATINDEX("%_m%",FName) FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FName Tom 2 Jim 2 Lily 0 Kelly 0 Sam 2 Kerry 0 Smith 1 BillGates 0
REPLICATE()函數用來獲得一個子字符串重複了若干次所組成的字符串,它和MYSQL中的REPEAT()函數是同樣的,其參數格式以下:
REPLICATE (str,count)
參數str爲子字符串,而count爲重複次數。
下面的SQL語句用於將每一個人的姓名重複n次,n等於體重與20的整除結果:
SELECT FName,FWeight,CAST(FWeight/20 AS INT),REPLICATE(FName, CAST(FWeight/20 AS INT)) FROM T_Person
和MYSQL同樣,MYSQL中一樣提供了一個簡化REPLICATE()調用的函數SPACE(N),它用來獲得一個有N空格字符組成的字符串,能夠看作是REPLICATE (" ",N)的等價形式。
REVERSE()函數用來將一個字符串的順序顛倒,下面的SQL語句將全部人員的姓名進行了顛倒:
SELECT FName, REVERSE(FName) FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FName Tom moT Jim miJ Lily yliL Kelly ylleK Sam maS Kerry yrreK Smith htimS BillGates setaGlliB
ISDATE()函數用來肯定輸入表達式是否爲有效日期。若是輸入表達式是有效日期,那麼ISDATE 返回 1;不然,返回 0。其參數格式以下:
ISDATE ( expression )
expression參數爲要驗證其是否爲日期的表達式。expression能夠是text、ntext表達式和image表達式之外的任意表達式,能夠隱式轉換爲nvarchar。
下面的SQL語句演示了這個函數的使用:
SELECT ISDATE(NULL) as d1, ISDATE("13/43/3425") as d2, ISDATE("1995-10-1a") as d3, ISDATE(19920808) as d4, ISDATE("1/23/95") as d5, ISDATE("1995-10-1") as d6, ISDATE("19920808") as d7, ISDATE(" Abc") as d8
執行完畢咱們就能在輸出結果中看到下面的執行結果:
d1 d2 d3 d4 d5 d6 d7 d8 0 0 0 1 0 1 1 0
ISNUMERIC ()函數用來肯定表達式是否爲有效的數值類型。若是輸入表達式的計算值爲有效的整數、浮點數、money 或decimal 類型時,ISNUMERIC 返回 1;不然返回 0。
其參數格式以下:
ISNUMERIC ( expression )
expression參數爲要計算的表達式。下面的SQL語句演示了這個函數的使用:
SELECT
ISNUMERIC(NULL) as d1,
ISNUMERIC("13/43/3425") as d2,
ISNUMERIC("30a.8") as d3,
ISNUMERIC(19920808) as d4,
ISNUMERIC("1/23/95") as d5,
ISNUMERIC("3E-3") as d6,
ISNUMERIC("19920808") as d7,
ISNUMERIC("-30.3") as d8
執行完畢咱們就能在輸出結果中看到下面的執行結果:
```java d1 d2 d3 d4 d5 d6 d7 d8 0 0 0 1 0 1 1 1
APP_NAME()函數返回當前會話的應用程序名稱;CURRENT_USER函數(注意這個函數不能帶括號調用)返回當前登錄用戶名;HOST_NAME()函數返回工做站名。下面的SQL語句演示了這幾個函數的使用:
SELECT APP_NAME() as appname,CURRENT_USER as cu,HOST_NAME() as hostname
執行完畢咱們就能在輸出結果中看到下面的執行結果:
appname cu hostname jTDS dbo YANGZK
與MYSQL相似,MSSQLServer 中一樣提供了生成全局惟一字符串的函數NEWID(),下面生成三個UUID 字符串:
SELECT NEWID() AS id1,NEWID() AS id2
執行完畢咱們就能在輸出結果中看到下面的執行結果:
id1 id2
705FAA88-12B9-4C52-9B77-589DD20256C3 A110A5E5-92C7-461F-91F8-BF35129FE7B4
Oracle中的獨有函數
填充函數
與MYSQL相似,Oracle中也提供了用於進行字符串填充的函數LPAD()、RPAD(),其參數格式以下:
LPAD(char1,n [,char2]) RPAD(char1, n [,char2])
與MYSQL中不一樣的是,Oracle中LPAD()和RPAD()函數的第三個參數是能夠省略的,若是省略第三個參數,則使用單個空格進行填充。
下面的SQL語句分別將每一個人的姓名用星號左填充和井號右填充到5個字符:
SELECT FName,LPAD(FName,5,"*"),RPAD(FName,5,"#") FROM T_Person
執行完畢咱們就能在輸出結果中看到下面的執行結果:
FNAME LPAD(FNAME,5,*) RPAD(FNAME,5,#) Tom **Tom Tom## Jim **Jim Jim## Lily *Lily Lily# Kelly Kelly Kelly Sam **Sam Sam## Kerry Kerry Kerry Smith Smith Smith BillGates BillG BillG
Oracle中的LAST_DAY()函數能夠用來計算指定日期所在月份的最後一天的日期。下面的SQL語句用於計算每一個人出生時當月的最後一天的日期:
SELECT FName,FBirthDay,LAST_DAY(FBirthDay) FROM T_Person WHERE FBirthDay IS NOT NULL
和MYSQL相似,Oracle中提供了用來計算一個集合中的最大和最小值的GREATEST()函數和LEAST()函數。其使用方法和MYSQL一致:
SELECT GREATEST(2,7,1,8,30,4,5566,99,2,222,12),LEAST(2,7,1,8,30,4,3,99,-2,222,12) FROM DUAL
執行完畢咱們就能在輸出結果中看到下面的執行結果:
GREATEST(2,7,1,8,30,4,5566,99,2,222,12) LEAST(2,7,1,8,30,4,3,99,-2,222,12) 5566 -2
USER函數用來取得當前登陸用戶名,注意使用這個函數的時候不能使用括號形式的空參數列表,也就是USER()這種使用方式是不對的。正確使用方式以下:
SELECT USER FROM DUAL
執行完畢咱們就能在輸出結果中看到下面的執行結果:
USER SYS
USERENV()函數用來取得當前登陸用戶相關的環境信息,這個函數的返回值爲字符串類型,須要根據狀況將返回值轉換爲合適的類型。它的參數格式以下:
USERENV(option)
option參數爲要取得的環境信息的名稱,可取值以下:
可取值說明
"ISDBA" 若是當前登陸用戶有DBA的角色則返回TRUE,不然返回FALSE "LANGUAGE" 返回當前登陸用戶使用的語言和字符集,返回格式爲「語言.字符集」 "TERMINAL" 返回當前登陸用戶的操做系統標識 "SESSIONID" 返回當前登陸用戶的會話標識 "ENTRYID" 返回當前登陸用戶的認證標識 "LANG" 返回當前用戶使用的語言,它比"LANGUAGE"的返回值短 "INSTANCE" 返回當前實例的標識
下面的SQL語句用來取得當前登陸用戶的語言信息和權限信息:
SELECT USERENV("ISDBA") AS ISDBA,USERENV("LANGUAGE") AS LANGUAGE,USERENV("LANG") AS LANG FROM DUAL
執行完畢咱們就能在輸出結果中看到下面的執行結果:
ISDBA LANGUAGE LANG
TRUE SIMPLIFIED CHINESE_CHINA.AL32UTF8 ZHS