1. 程式人生 > >字串的拼接

字串的拼接

SQL允許兩個或者多個欄位之間進行計算,字串型別的欄位也不例外。比如我們需要以“工號+姓名”的方式在報表中顯示一個員工的資訊,那麼就需要把工號和姓名兩個字串型別的欄位拼接計算;再如我們需要在報表中在每個員工的工號前增加“Old”這個文字。

這時候就需要我們對字串型別的欄位(包括字串型別的常量欄位)進行拼接。在不同的資料庫系統下的字串拼接是有很大差異的,因此這裡我們將講解主流資料庫下的字串拼接的差異。

需要注意的是,在Java、C#等程式語言中字串是用半形的雙引號來包圍的,但是在有的資料庫系統的SQL語法中雙引號有其他的含義(比如列的別名),而所有的資料庫系統都支援用單引號包圍的形式定義的字串,所以建議讀者使用以單引號包圍的形式定義的字串,而且本書也將使用這種方式。

  • MYSQL

在Java、C#等程式語言中字串的拼接可以通過加號“+”來實現,比如:"1"+"3"、"a"+"b"。在MYSQL中也可以使用加號“+”來連線兩個字串,比如下面的SQL:


SELECT "12"+"33",FAge+"1" FROM T_Employee 

執行完畢我們就能在輸出結果中看到下面的執行結果:


"12"+"33" FAge+"1"

45            26 45 29 45 24 45 26 45 29 45 28 45 24 45 29 45 23 

仔細觀察第一列,驚訝嗎?這個列的顯示結果並不是我們希望的“1233”,而是把“12”和“33”兩個字串當成數字來求兩個數的和了;同樣將一個數字與一個字串用加號“+”連線也是同樣的效果,比如這裡的第二列。

在MYSQL中,當用加號“+”連線兩個欄位(或者多個欄位)的時候,MYSQL會嘗試將欄位值轉換為數字型別(如果轉換失敗則認為欄位值為0),然後進行欄位的加法運算。因此,當計算的"12"+"33"的時候,MYSQL會將“12”和“33”兩個字串嘗試轉換為數字型別的12和33,然後計算12+33的值,這就是為什麼我們會得到45的結果了。同樣道理,在計算FAge+"1"的時候,由於FAge為數字型別,所以不需要進行轉換,而"1"為字串型別,所以MYSQL將"1"嘗試轉換為數字1,然後計算FAge+1做為計算列的值。

MYSQL會嘗試將加號兩端的欄位值嘗試轉換為數字型別,如果轉換失敗則認為欄位值為0,比如我們執行下面的SQL語句:


SELECT "abc"+"123",FAge+"a" FROM T_Employee 

執行完畢我們就能在輸出結果中看到下面的執行結果:


"abc"+"123" FAge+"a"

    123         25 123 28 123 23 123 25 123 28 123 27 123 23 123 28 123 22 

在MYSQL中進行字串的拼接要使用CONCAT函式,CONCAT函式支援一個或者多個引數,引數型別可以為字串型別也可以是非字串型別,對於非字串型別的引數MYSQL將嘗試將其轉化為字串型別,CONCAT函式會將所有引數按照引數的順序拼接成一個字串做為返回值。比如下面的SQL語句用於將使用者的多個欄位資訊以一個計算欄位的形式查詢出來:


SELECT CONCAT("工號為:",FNumber,"的員工的幸福指數:",FSalary/(FAge-21)) FROM T_Employee 

執行完畢我們就能在輸出結果中看到下面的執行結果:


CONCAT("工號為:",FNumber,"的員工的幸福指數:",FSalary/(FAge-21))

工號為:DEV001 的員工的幸福指數:2075.000000

工號為:DEV002 的員工的幸福指數:328.685714 工號為:HR001的員工的幸福指數:1100.440000 工號為:HR002的員工的幸福指數:1300.090000 工號為:IT001 的員工的幸福指數:557.142857 工號為:IT002 的員工的幸福指數:466.666667 工號為:SALES001 的員工的幸福指數:2500.000000 工號為:SALES002 的員工的幸福指數:885.714286 工號為:SALES003 的員工的幸福指數:1200.000000 

CONCAT支援只有一個引數的用法,這時的CONCAT可以看作是一個將這個引數值嘗試轉化為字串型別值的函式。MYSQL中還提供了另外一個進行字串拼接的函式CONCAT_WS,CONCAT_WS可以在待拼接的字串之間加入指定的分隔符,它的第一個引數值為採用的分隔符,而剩下的引數則為待拼接的字串值,比如執行下面的SQL:


SELECT CONCAT_WS(",",FNumber,FAge,FDepartment,FSalary) FROM T_Employee

執行完畢我們就能在輸出結果中看到下面的執行結果:


CONCAT_WS(",",FNumber,FAge,FDepartment,FSalary)

DEV001,25,Development,8300.00

DEV002,28,Development,2300.80 HR001,23,HumanResource,2200.88 HR002,25,HumanResource,5200.36 IT001,28,InfoTech,3900.00 IT002,27,InfoTech,2800.00 SALES001,23,Sales,5000.00 SALES002,28,Sales,6200.00 SALES003,22,Sales,1200.00 

MSSQLServer

與MYSQL不同,MSSQLServer中可以直接使用加號“+”來拼接字串。比如執行下面的SQL語句:


SELECT "工號為"+FNumber+"的員工姓名為"+Fname FROM T_Employee WHERE FName IS NOT NULL 

執行完畢我們就能在輸出結果中看到下面的執行結果:


工號為 DEV001 的員工姓名為Tom

工號為DEV002 的員工姓名為Jerry

工號為HR001的員工姓名為Jane

工號為HR002的員工姓名為Tina

工號為IT001 的員工姓名為Smith

工號為SALES001 的員工姓名為John

工號為SALES002 的員工姓名為Kerry

工號為SALES003 的員工姓名為Stone

Oracle

Oracle中使用“||”進行字串拼接,其使用方式和MSSQLServer中的加號“+”一樣。

比如執行下面的SQL語句:


SELECT "工號為"||FNumber||"的員工姓名為"||FName FROM T_Employee WHERE FName IS NOT NULL 

執行完畢我們就能在輸出結果中看到下面的執行結果:


工號為||FNUMBER||的員工姓名為||FNAME

工號為DEV001 的員工姓名為Tom

工號為DEV002 的員工姓名為Jerry

工號為SALES001 的員工姓名為John

工號為SALES002 的員工姓名為Kerry

工號為SALES003 的員工姓名為Stone

工號為HR001的員工姓名為Jane

工號為HR002的員工姓名為Tina

工號為IT001 的員工姓名為Smith

除了“||”,Oracle還支援使用CONCAT()函式進行字串拼接,比如執行下面的SQL語句:


SELECT CONCAT("工號:",FNumber) FROM T_Employee

執行完畢我們就能在輸出結果中看到下面的執行結果:


CONCAT(工號:,FNUMBER)

工號:DEV001

工號:DEV002

工號:HR001 工號:HR002 工號:IT001 工號:IT002 工號:SALES001 工號:SALES002 工號:SALES003 

如果CONCAT中連線的值不是字串,Oracle會嘗試將其轉換為字串,比如執行下面的SQL語句:


SELECT CONCAT("年齡:",FAge) FROM T_Employee

執行完畢我們就能在輸出結果中看到下面的執行結果:


CONCAT(年齡:,FAGE)

年齡:25

年齡:28

年齡:23 年齡:28 年齡:22 年齡:23 年齡:25 年齡:28 年齡:27 

與MYSQL的CONCAT()函式不同,Oracle的CONCAT()函式只支援兩個引數,不支援兩個以上字串的拼接,比如下面的SQL語句在Oracle中是錯誤的:


SELECT CONCAT("工號為",FNumber,"的員工姓名為",FName) FROM T_Employee WHERE FName IS NOT NULL 

執行以後Oracle會報出下面的錯誤資訊:

引數個數無效

如果要進行多個字串的拼接的話,可以使用多個CONCAT()函式巢狀使用,上面的SQL可以如下改寫:


SELECT CONCAT(CONCAT(CONCAT("工號為",FNumber),"的員工姓名為"),FName) FROM T_Employee WHERE FName IS NOT NULL 

執行完畢我們就能在輸出結果中看到下面的執行結果:


CONCAT(CONCAT(CONCAT(工號為,FNUMBER),的員工姓名為),FNAME)

工號為DEV001 的員工姓名為Tom

工號為DEV002 的員工姓名為Jerry

工號為SALES001 的員工姓名為John

工號為SALES002 的員工姓名為Kerry

工號為SALES003 的員工姓名為Stone

工號為HR001的員工姓名為Jane

工號為HR002的員工姓名為Tina

工號為IT001 的員工姓名為Smith

DB2

DB2中使用“||”進行字串拼接,其使用方式和MSSQLServer中的加號“+”一樣。比如執行下面的SQL語句:


SELECT "工號為"||FNumber||"的員工姓名為"||FName FROM T_Employee WHERE FName IS NOT NULL 

執行完畢我們就能在輸出結果中看到下面的執行結果:


1

工號為DEV001 的員工姓名為Tom

工號為DEV002 的員工姓名為Jerry

工號為SALES001 的員工姓名為John

工號為SALES002 的員工姓名為Kerry

工號為SALES003 的員工姓名為Stone

工號為HR001的員工姓名為Jane

工號為HR002的員工姓名為Tina

工號為IT001 的員工姓名為Smith

除了“||”,DB2還支援使用CONCAT()函式進行字串拼接,比如執行下面的SQL語句:


SELECT CONCAT("工號:",FNumber) FROM T_Employee

執行完畢我們就能在輸出結果中看到下面的執行結果:


1

工號:DEV001

工號:DEV002

工號:HR001

工號:HR002

工號:IT001 工號:IT002 工號:SALES001 工號:SALES002 工號:SALES003 

與Oracle不同,如果CONCAT中連線的值不是字串,則DB2不會嘗試進行型別轉換而是報出錯誤資訊,比如執行下面的SQL語句是錯誤的:


SELECT CONCAT("年齡:",FAge) FROM T_Employee

執行以後DB2會報出下面的錯誤資訊:

未找到型別為"FUNCTION" 命名為 "CONCAT" 且具有相容自變數的已授權例程與MYSQL的CONCAT()函式不同,DB2的CONCAT()函式只支援兩個引數,不支援兩個以上字串的拼接,比如下面的SQL語句在Oracle中是錯誤的:


SELECT CONCAT("工號為",FNumber,"的員工姓名為",FName) FROM T_Employee WHERE FName IS NOT NULL 

執行以後Oracle會報出下面的錯誤資訊:

未找到型別為"FUNCTION" 命名為 "CONCAT" 且具有相容自變數的已授權例程

如果要進行多個字串的拼接的話,可以使用多個CONCAT()函式巢狀使用,上面的SQL可以如下改寫:


SELECT CONCAT(CONCAT(CONCAT("工號為",FNumber),"的員工姓名為"),FName) FROM T_Employee WHERE FName IS NOT NULL 

執行完畢我們就能在輸出結果中看到下面的執行結果:


1

工號為DEV001 的員工姓名為Tom

工號為DEV002 的員工姓名為Jerry

工號為SALES001 的員工姓名為John

工號為SALES002 的員工姓名為Kerry

工號為SALES003 的員工姓名為Stone

工號為HR001的員工姓名為Jane

工號為HR002的員工姓名為Tina

工號為IT001 的員工姓名為Smith