1. 程式人生 > >各資料庫系統獨有函式

各資料庫系統獨有函式

前邊我們講解了一些常用的函式,這些函式不是在各個主流資料庫系統中有著相同的名稱和用法,就是在各個主流資料庫系統中有等價的實現,這些函式可以基本滿足我們大部分需求。不過在各個主流資料庫系統還提供了一些自身獨有的函式,這些函式在其他的資料庫系統中一般都沒有等價的實現,使用這些函式以後會給系統的跨資料庫移植帶來一定的麻煩,不過如果系統對跨資料庫移植沒有要求的話,那麼使用這些函式不僅能提高開發速度,而且能夠更好發揮資料庫系統的效能,所以瞭解它們還是非常有必要的,因此這裡我們專門安排一節來介紹這些函式。

  • MYSQL中的獨有函式

  • IF()函式

使用CASE函式可以實現非常複雜的邏輯判斷,可是若只是實現“如果符合條件則返回A,否則返回B”這樣簡單的判斷邏輯的話,使用CASE函式就過於繁瑣,如下:


CASE WHEN condition THENA ELSE B END

MYSQL提供了IF()函式用於簡化這種邏輯判斷,其語法格式如下:


IF(expr1,expr2,expr3)

如果expr1 為真(expr1 <> 0 以及expr1<>NULL),那麼IF()返回expr2,否則返回expr3。IF()返回一個數字或字串,這取決於它被使用的語境。

這裡使用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()函式

CONV()函式用於對數字進行進位制轉換,比如將十進位制的26轉換為2進位制顯示,其引數格式如下:


CONV(N,from_base,to_base)

將數字N從from_base進位制轉換到to_base進位制,並以字串表示形式返回。from_base和to_base的最小值為2,最大值為36。如果to_base是一個負值,N 將被看作為是一個有符號數字。否則,N 被視為是無符號的。

下面的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()函式用來得到一個子字串重複了若干次所組成的字串,其引數格式如下:


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客戶”、“高階客戶”、“普通客戶”這樣的匹配目標字串當作集合處理,而將“1、2、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則是普通客戶,在製作報表的時候顯然不應該把1、2、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 ()函式

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()函式用來確定輸入表示式是否為有效日期。如果輸入表示式是有效日期,那麼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()函式

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