db2case语句_DB2 常用的SQL语句
1、組合語(yǔ)句執(zhí)行
BEGINATOMIC
表達(dá)式1分號(hào)空格/回車(chē)
表達(dá)式2分號(hào)空格/回車(chē)
END
2、應(yīng)該限制訪問(wèn)權(quán)限的表(應(yīng)該撤銷這些表PUBLIC SELECT訪問(wèn)權(quán))
SYSCAT.DBAUTH
SYSCAT.TABAUTH
SYSCAT.PACKAGEAUTH
SYSCAT.INDEXAUTH
SYSCAT.COLAUTH
SYSCAT.PASSTHRUAUTH
SYSCAT.SCHEMAAUTH
比較有用的目錄表
SYSCAT.COLUMNS:包含每一行對(duì)應(yīng)于表或視圖中定義的列
SYSCAT.INDEXCOLUSE:包含每一行包含的所有列
SYSCAT.INDEXES:包含每一行對(duì)應(yīng)于表或視圖中定義的每個(gè)索引
SYSCAT.TABLES:所創(chuàng)建每個(gè)表,視圖,別名對(duì)應(yīng)其中一行
SYSCAT.VIEWS:所創(chuàng)建每個(gè)視圖對(duì)應(yīng)其中一行或幾行
通過(guò)索引保持?jǐn)?shù)據(jù)唯一性:CREATE UNIQUE INDEX INDEXNAME ON TABLE (COLUMN)
消除重復(fù)行:SELECT DISTINCT COLUMN FROM TABLE
3、DB2關(guān)于時(shí)間的一些函數(shù)
得到當(dāng)前時(shí)間的年份、月份、天、小時(shí)等等:
YEAR (current timestamp)
MONTH (current timestamp)
DAY (current timestamp)
HOUR (current timestamp)
MINUTE (current timestamp)
SECOND (current timestamp)
MICROSECOND (current timestamp)
分別得到當(dāng)時(shí)的日期和時(shí)間
DATE (current timestamp)
TIME (current timestamp)
關(guān)于時(shí)間的一些計(jì)算:
current date + 1 YEAR
current date + 3 YEARS + 2 MONTHS + 15 DAYS
current time + 5 HOURS - 3 MINUTES + 10 SECONDS
計(jì)算兩個(gè)日期之間有多少天:
days (current date) - days (date(’1999-10-22′))
得到去除毫秒的當(dāng)前時(shí)間:
CURRENT TIMESTAMP - MICROSECOND (current timestamp) MICROSECONDS
將時(shí)間轉(zhuǎn)換成字符串:
char(current date)
char(current time)
char(current date + 12 hours)
將字符串轉(zhuǎn)換成時(shí)間:
TIMESTAMP (’2002-10-20-12.00.00.000000′)
TIMESTAMP (’2002-10-20 12:00:00′)
DATE (’2002-10-20′)
DATE (’10/20/2002′)
TIME (’12:00:00′)
TIME (’12.00.00′)
注意:在DB2的命令編輯器中可以輸入SQL語(yǔ)句和DB2中的內(nèi)部命令。要想顯示當(dāng)前時(shí)間的話,不能直接輸入current time,這個(gè)只能在SQL語(yǔ)言中引用,要想顯示有下面方式:
1)VALUES(current time)
2)SELECT?CURRENT TIME FROM SYSIBM.SYSDUMMY1
這個(gè)與SQL SERVER2000中不一樣,在SQL SERVER2000中可以輸入Getdate()得到時(shí)間,既可以顯示,也可以在語(yǔ)句SQL中用。
4、所有返回前N條數(shù)據(jù)的表達(dá)式
在SQL SERVER2000中使用TOP N格式
比如:SELECT TOP 10 CARDNO FROM CARD
在DB2中使用fetch first N rows only格式
比如:SELECT CARDNO FROM SEALCARD fetch first 10 rows only
5、函數(shù)使用
查看系統(tǒng)函數(shù):SELECT * FROM?SYSibm.sysfunctions;
比如:ABS(-89)可以作為值輸入到SQL中,但是要想在命令編輯器中顯示函數(shù)的結(jié)果的話可以用下列方式:
1)SELECT ABS(-89) FROM SYSIBM.SYSDUMMY1;
2)VALUES ABS(-89);
6、存儲(chǔ)過(guò)程
在進(jìn)行DB2存儲(chǔ)過(guò)程開(kāi)發(fā)時(shí),我們可以利用很多DB2自帶的工具,例如開(kāi)發(fā)中心,控制中心等。但有時(shí)使用腳本能帶給開(kāi)發(fā)人員更大的靈活性和更高的工作效率。
在開(kāi)始開(kāi)發(fā)一個(gè)新的或修改一個(gè)已存在的存儲(chǔ)過(guò)程時(shí),我們通常會(huì)進(jìn)行下面一些準(zhǔn)備工作:
1.查看該存儲(chǔ)過(guò)程會(huì)用到的表的表結(jié)構(gòu)、字段類型、相關(guān)索引和示例數(shù)據(jù)。
2.查看相關(guān)的存儲(chǔ)過(guò)程或用戶自定義函數(shù)(UDF)的定義。
3.查找無(wú)效的存儲(chǔ)過(guò)程并生成綁定語(yǔ)句。
4.如某個(gè)表發(fā)生了改變,查看依賴于該表的所有視圖、存儲(chǔ)過(guò)程和用戶自定義函數(shù)(UDF)
雖然上述信息都可以通過(guò)DB2提供的開(kāi)發(fā)工具和管理工具獲得,但是通過(guò)腳本可以更快速的獲得所需信息,并且可以重復(fù)執(zhí)行。
使用腳本完成上述任務(wù)的關(guān)鍵是理解和使用DB2的系統(tǒng)表。我們先簡(jiǎn)單回顧一下有關(guān)的DB2的系統(tǒng)表和視圖:
1.syscat.routines:存儲(chǔ)所有的存儲(chǔ)過(guò)程和用戶自定義函數(shù)(UDF)信息。其中routinename字段為存儲(chǔ)過(guò)程或用戶自定義函數(shù)(UDF)的名稱,routinetype字段表示該記錄表示的是存儲(chǔ)過(guò)程(P)還是用戶自定義函數(shù)(F),lib_id字段為存儲(chǔ)過(guò)程編譯后生成的包序列號(hào),origin字段表示該存儲(chǔ)過(guò)程或用戶自定義函數(shù)的出處(Q表示是由SQL組成的,E表示用戶定義的且是外部的),valid字段表示該存儲(chǔ)過(guò)程或用戶自定義函數(shù)是否有效,如果origin字段不是Q的話,該域?yàn)榭铡?/p>
2.syscat.packages:存儲(chǔ)所有被綁定的程序包。其中pkgname表示包名稱,valid字段表示該包是否合法。
3.syscat.packagedep:存儲(chǔ)關(guān)于程序包的依賴關(guān)系。其中pkgname字段表示程序包名,btype字段表示被依賴對(duì)象的類型,bname字段表示被依賴對(duì)象的名稱。
4.syscat.routinedep:存儲(chǔ)關(guān)于程序(routine)的依賴關(guān)系。其中routinename字段表示程序名,btype字段表示被依賴對(duì)象的類型,bname字段表示被依賴對(duì)象的名稱。
5.syscat.viewdep:存儲(chǔ)了關(guān)于視圖的依賴關(guān)系。其中viewname字段表示視圖名,btype字段表示被依賴對(duì)象的類型,bname字段表示被依賴對(duì)象的名稱。
回顧并了解了上述系統(tǒng)表和視圖,我們就可以很容易的創(chuàng)建腳本以完成前面提到的開(kāi)發(fā)存儲(chǔ)過(guò)程所要做的準(zhǔn)備工作。
1.查看該表結(jié)構(gòu)、字段類型、相關(guān)索引和示例數(shù)據(jù)
雖然我們可以查詢sysibm.systables表獲得表結(jié)構(gòu),但有一種更簡(jiǎn)便的方法來(lái)獲取表結(jié)構(gòu),即使用db2look工具。該工具可以生成創(chuàng)建該表和相關(guān)的索引的DDL。如我們要獲取指定數(shù)據(jù)庫(kù)中指定表的結(jié)構(gòu)和前20條數(shù)據(jù)作為參考,可編寫(xiě)腳本viewtbl.cmd如下,傳入?yún)?shù)分別為數(shù)據(jù)庫(kù)名和表名。
@echo ------------------ DDL of table %2 and related index(ex)?------------------
@db2look -d %1 -t %2 -e
@echo?------------------ fisrt 20 rows in table %2 ------------------
@db2 select * from %2 fetch first 20 rows only
2.查看已存在的存儲(chǔ)過(guò)程和用戶自定義函數(shù)(UDF)的定義,將結(jié)果存入文件并自動(dòng)打開(kāi)結(jié)果文件。
可以從syscat.routines表中做簡(jiǎn)單查詢實(shí)現(xiàn)腳本viewrtn.cmd。
@db2 SELECT text?FROM SYSCAT.ROUTINES WHERE ROUTINENAME=upper('%1') > %1.sql
@start %1.sql
3.查看所有無(wú)效的存儲(chǔ)過(guò)程并生成綁定語(yǔ)句
刪除存儲(chǔ)過(guò)程引用的表會(huì)引起該存儲(chǔ)過(guò)程無(wú)效。無(wú)效存儲(chǔ)過(guò)程可以采用查詢syscat.routines和syscat.packages的方法獲得:
SELECT
RTRIM(r.routineschema) || '.' || RTRIM(r.routinename) AS spname?,
RTRIM(r.routineschema) || '.' || 'P'||SUBSTR(CHAR(r.lib_id+10000000),2) AS pkgname
FROM
SYSCAT.routines r
WHERE
r.routinetype = 'P'
AND (
(r.origin = 'Q' AND r.valid != 'Y')
OR EXISTS (
SELECT 1 FROM syscat.packages
WHERE pkgschema = r.routineschema
AND pkgname = 'P'||SUBSTR(CHAR(r.lib_id+10000000),2)
AND valid !='Y'
)
)
ORDER BY spname
注意要同時(shí)查詢syscat.routines和syscat.packages表,因?yàn)樵诔绦虬鼰o(wú)效時(shí)syscat.routines中的valid值仍可能為Y。
如果要自動(dòng)生成重新綁定語(yǔ)句,只需將上述SQL改寫(xiě)并存成invalidSP.cmd:
@echo off
db2 "SELECT '@db2 rebind package '|| RTRIM(r.routineschema) || '.' || 'P'||SUBSTR(CHAR(r.lib_id+10000000),2)||' resolve any' FROM SYSCAT.routines r WHERE r.routinetype = 'P' AND ((r.origin = 'Q' AND r.valid != 'Y') OR EXISTS (SELECT 1 FROM syscat.packages WHERE pkgschema = r.routineschema AND pkgname = 'P'||SUBSTR(CHAR(r.lib_id+10000000),2) AND valid !='Y') )" >rebindsp.bat
4.查看某個(gè)表所依賴的視圖、存儲(chǔ)過(guò)程和用戶自定義函數(shù)(UDF)
使用上述系統(tǒng)視圖,我們很容易編寫(xiě)出腳本:
@echo off
echo --- dependent SPs ---
db2 "select proc.procschema, proc.procname from syscat.routines r, syscat.procedures proc, syscat.packagedep pdep where pdep.bname=upper('%2') and pdep.bschema=upper('%1') and r.specificname=proc.specificname AND pdep.pkgname = 'P'||SUBSTR(CHAR(r.lib_id+10000000),2)"
echo --- dependent UDF ---
db2 select routineschema, routinename from syscat.routinedep where bschema = upper('%1')?and bname = upper('%2') and btype ='T'?order by bname
echo --- dependent view ---
db2 select viewschema, viewname from syscat.viewdep where bschema = upper('%1')?and bname = upper('%2') and btype ='T' order by bname
行業(yè)借鑒經(jīng)驗(yàn):提高DB2存儲(chǔ)過(guò)程性能和健壯性的3個(gè)最佳實(shí)踐
最佳實(shí)踐1:在創(chuàng)建存儲(chǔ)過(guò)程語(yǔ)句中提供必要的參數(shù)
創(chuàng)建存儲(chǔ)過(guò)程語(yǔ)句(CREATE PROCEDURE)可以包含很多參數(shù),雖然從語(yǔ)法角度講它們不是必須的,但是在創(chuàng)建存儲(chǔ)過(guò)程時(shí)提供這些參數(shù)可以提高執(zhí)行效率。下面是一些常用的參數(shù):
l容許SQL(allowed-SQL)
容許SQL(allowed-SQL)子句的值指定了存儲(chǔ)過(guò)程是否會(huì)使用SQL語(yǔ)句,如果使用,其類型如何。它的可能值如下所示:
NO SQL:表示存儲(chǔ)過(guò)程不能夠執(zhí)行任何SQL語(yǔ)句。
CONTAINS SQL:表示存儲(chǔ)過(guò)程可以執(zhí)行SQL語(yǔ)句,但不會(huì)讀取SQL數(shù)據(jù),也不會(huì)修改SQL數(shù)據(jù)。
READS SQL DATA:表示在存儲(chǔ)過(guò)程中包含不會(huì)修改SQL數(shù)據(jù)的SQL語(yǔ)句。也就是說(shuō)該儲(chǔ)存過(guò)程只從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù)。
MODIFIES SQL DATA:表示存儲(chǔ)過(guò)程可以執(zhí)行任何SQL語(yǔ)句。即可以對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增加、刪除和修改。
如果沒(méi)有明確聲明allowed-SQL,其默認(rèn)值是MODIFIES SQL DATA。不同類型的存儲(chǔ)過(guò)程執(zhí)行的效率是不同的,其中NO SQL效率最好,MODIFIES SQL DATA最差。如果存儲(chǔ)過(guò)程只是讀取數(shù)據(jù),但是因?yàn)闆](méi)有聲明allowed-SQL類型,它會(huì)被當(dāng)作對(duì)數(shù)據(jù)進(jìn)行修改的存儲(chǔ)過(guò)程來(lái)執(zhí)行,這顯然會(huì)降低程序的執(zhí)行效率。因此創(chuàng)建存儲(chǔ)過(guò)程時(shí),應(yīng)當(dāng)明確聲明其allowed-SQL類型。
l返回結(jié)果集個(gè)數(shù)(DYNAMIC RESULT SETS n)
存儲(chǔ)過(guò)程能夠返回0個(gè)或者多個(gè)結(jié)果集。為了從存儲(chǔ)過(guò)程中返回結(jié)果集,需要執(zhí)行如下步驟:
在CREATE PROCEDURE語(yǔ)句的DYNAMIC RESULT SETS子句中聲明存儲(chǔ)過(guò)程將要返回的結(jié)果集的數(shù)量。如果這里聲明的返回結(jié)果集的數(shù)量小于存儲(chǔ)過(guò)程中實(shí)際返回的結(jié)果集數(shù)量,在執(zhí)行該存儲(chǔ)過(guò)程的時(shí)候,DB2會(huì)返回一個(gè)警告。
使用WITH RETURN子句,在存儲(chǔ)過(guò)程體中聲明游標(biāo)。
為結(jié)果集打開(kāi)游標(biāo)。當(dāng)存儲(chǔ)過(guò)程返回的時(shí)候,保持游標(biāo)打開(kāi)。
在創(chuàng)建存儲(chǔ)過(guò)程時(shí)指定返回結(jié)果集的個(gè)數(shù)可以幫助程序員驗(yàn)證存儲(chǔ)過(guò)程是否返回了所期待數(shù)量的結(jié)果集,提高了程序的完整性。
最佳實(shí)踐2:對(duì)輸入?yún)?shù)進(jìn)行必要的的檢查和預(yù)處理
無(wú)論使用哪種編程語(yǔ)言,對(duì)輸入?yún)?shù)的判斷都是必須的。正確的參數(shù)驗(yàn)證是保證程序良好運(yùn)行的前提。同樣的,在DB2存儲(chǔ)過(guò)程中對(duì)輸入?yún)?shù)的驗(yàn)證和處理也是很重要的。正確的驗(yàn)證和預(yù)處理操作包括:
如果輸入?yún)?shù)錯(cuò)誤,存儲(chǔ)過(guò)程應(yīng)返回一個(gè)明確的值告訴客戶應(yīng)用,然后客戶應(yīng)用可以根據(jù)返回的值進(jìn)行處理,或者向存儲(chǔ)過(guò)程提交新的參數(shù),或者去調(diào)用其他的程序。
根據(jù)業(yè)務(wù)邏輯,對(duì)輸入?yún)?shù)作一定的預(yù)處理,如大小寫(xiě)的轉(zhuǎn)換,NULL與空字符串或0的轉(zhuǎn)換等。
在DB2儲(chǔ)存過(guò)程開(kāi)發(fā)中,如需要遇到對(duì)空(NULL)進(jìn)行初始化,我們可以使用COALESCE函數(shù)。該函數(shù)返回第一個(gè)非NULL的參數(shù)。例如,COALESCE(piName,''),如果變量piName為NULL,那么函數(shù)會(huì)返回'',否則就會(huì)返回piName本身的值。因此,可以用下面的代碼檢查piName是否非NULL并且非空字符串:
SETpoGenStatus=0;
SETpiName=RTRIM(COALESCE(piName,''));
IF(piName='')
THEN
SETpoGenStatus=34100;
RETURNpoGenStatus;
ENDIF;
同理,使用COALESCE可以對(duì)任何類型的輸入?yún)?shù)進(jìn)行初始化或驗(yàn)證。下面是對(duì)參數(shù)初始化規(guī)則的一個(gè)總結(jié):
1.輸入?yún)?shù)為字符類型,且允許為NULL的,如希望缺省值為空字符串,可以使用COALESCE(inputParameter, '')把NULL轉(zhuǎn)換成空字符串;
2.輸入類型為整型,且允許為NULL的,如希望缺省值為0,可以使用COALESCE(inputParameter,0),把NULL轉(zhuǎn)換成0;
3.輸入?yún)?shù)為字符類型,且不允許是NULL或空字符串的,可以使用RTRIM(COALESCE(inputParameter, ''))把NULL轉(zhuǎn)換成空字符串,然后驗(yàn)證函數(shù)返回值是否為空字符串;
4.輸入類型為整型,且不允許是NULL的,不需要使用COALESCE函數(shù),直接使用IS NULL進(jìn)行驗(yàn)證。
最佳實(shí)踐3:異常(condition)處理
在存儲(chǔ)過(guò)程執(zhí)行的過(guò)程中,經(jīng)常因?yàn)閿?shù)據(jù)或者其他問(wèn)題產(chǎn)生異常(condition)。根據(jù)業(yè)務(wù)邏輯,存儲(chǔ)過(guò)程應(yīng)該對(duì)異常進(jìn)行相應(yīng)處理或直接返回給調(diào)用者。此處暫且將condition譯為異常以方便理解。實(shí)際上有些異常(condition)并非是由于錯(cuò)誤引起的。
當(dāng)存儲(chǔ)過(guò)程中的語(yǔ)句返回的SQLSTATE值超過(guò)00000的時(shí)候,就表明在存儲(chǔ)過(guò)程中產(chǎn)生了一個(gè)異常(condition),它表示出現(xiàn)了錯(cuò)誤、數(shù)據(jù)沒(méi)有找到或者出現(xiàn)了警告。為了處理存儲(chǔ)過(guò)程中出現(xiàn)的異常,我們必須在存儲(chǔ)過(guò)程體中聲明異常處理器(condition handler),它可以決定存儲(chǔ)過(guò)程怎樣響應(yīng)一個(gè)或者多個(gè)系統(tǒng)定義的異常或者自定義異常。
異常處理器類型(handler-type)有以下幾種:
lCONTINUE:在處理器操作完成之后,會(huì)繼續(xù)執(zhí)行產(chǎn)生這個(gè)異常語(yǔ)句之后的下一條語(yǔ)句。
lEXIT:在處理器操作完成之后,存儲(chǔ)過(guò)程會(huì)終止,并將控制返回給調(diào)用者。
lUNDO:在處理器操作執(zhí)行之前,DB2會(huì)回滾存儲(chǔ)過(guò)程中執(zhí)行過(guò)的SQL操作。在處理器操作完成之后,存儲(chǔ)過(guò)程會(huì)終止,并將控制返回給調(diào)用者。
異常處理器可以處理基于特定SQLSTATE值的自定義異常,或者處理系統(tǒng)預(yù)定義異常。系統(tǒng)預(yù)定義的3種異常如下所示:
lNOT FOUND:標(biāo)識(shí)導(dǎo)致SQLCODE值為+100或者SQLSATE值為02000的異常。這個(gè)異常通常在SELECT沒(méi)有返回行的時(shí)候出現(xiàn)。
lSQLEXCEPTIOIN:標(biāo)識(shí)導(dǎo)致SQLCODE值為負(fù)的異常。
lSQLWARNING:標(biāo)識(shí)導(dǎo)致警告異常或者導(dǎo)致正100以上的SQLCODE值的異常。
如果產(chǎn)生了NOT FOUND或者SQLWARNING異常,并且沒(méi)有為這個(gè)異常定義異常處理器,系統(tǒng)就會(huì)忽略這個(gè)異常,并且將控制流轉(zhuǎn)向下一個(gè)語(yǔ)句。如果產(chǎn)生了SQLEXCEPTION異常,并且沒(méi)有為這個(gè)異常定義異常處理器,那么存儲(chǔ)過(guò)程就會(huì)失敗,系統(tǒng)會(huì)將控制流返回調(diào)用者。因此如果開(kāi)發(fā)人員想改變這種異常處理流程,必須自定義異常處理器。例如,希望在出現(xiàn)SQLWARNING異常時(shí)也終止存儲(chǔ)過(guò)程,并將名為stmt的變量設(shè)為“ABORTED”,可以定義下面語(yǔ)句定義異常處理器:
DECLAREEXITHANDLERFORSQLEXCEPTION, SQLWARNING
SETstmt='ABORTED';
如果預(yù)定義異常集仍不能滿足需求,可以為特定的SQLSTATE值聲明自定義異常,然后再為這個(gè)異常定制異常聲明處理器。為特定的SQLSTATE值聲明自定義異常的語(yǔ)法如下:
DECLARE condition-name CONDITION FOR SQLSATE‘mysqlstate’
定義了異常和異常處理器后,在存儲(chǔ)過(guò)程執(zhí)行的任何都使用SIGNAL condition-name語(yǔ)句觸發(fā)這種自定義類型的異常。
異常處理器可以由單獨(dú)的存儲(chǔ)過(guò)程語(yǔ)句定義,也可以使用復(fù)合語(yǔ)句定義。注意在執(zhí)行復(fù)合語(yǔ)句的時(shí)候,SQLSATE和SQLCODE的值會(huì)被改變,如果需要保留異常前的SQLSATE和SQLCODE值,就需要在復(fù)合語(yǔ)句中的第一個(gè)語(yǔ)句把SQLSATE和SQLCODE賦予本地變量或參數(shù)。下面是一個(gè)例子:
DECLARECONTINUEHANDLERFORSQLEXCEPTION, SQLWARNING,NOTFOUND
BEGINNOTATOMIC
-- Capture SQLCODE & SQLSTATE?to local variables
SELECTSQLCODE, SQLSTATE
INTOhSqlcode, hSqlstate
FROMSYSIBM.SYSDUMMY1;
-- your handler statements below
……
END;
應(yīng)用難點(diǎn)技巧:使用Case讓你的SQL語(yǔ)句有條件的執(zhí)行
我們?cè)诰帉?xiě)SQL語(yǔ)句時(shí),常常遇到希望SQL能夠按條件執(zhí)行的情況。這里的條件不是指Where子句中的條件,而是指讓DB2根據(jù)條件執(zhí)行SQL的語(yǔ)句塊。大多數(shù)情況下我們可以使用case來(lái)實(shí)現(xiàn)。
例如,我們希望從員工表中查出員工的工資情況,如果小于20000,則標(biāo)志為low,20000到50000間為middle,否則為high。一般大家會(huì)想到先取出工資數(shù)據(jù)然后在Java代碼中做判斷,但我們也可以在SQL中完成上述操作。如下例:
select empno, sex, salary,
case
when salary < 20000 then 'low'
when salary >=20000 and salary <50000 then 'middle'
else 'high'
end as salaryclass
from employee
類似的,如果想在SQL語(yǔ)句中把性別翻譯成文字,也可以用case實(shí)現(xiàn),注意這兩條SQL語(yǔ)句使用了不同的case表達(dá)式寫(xiě)法:
select empno,
case sex
when 'M' then 'male'
when 'F' then 'female'
else 'invalid'
end,
salary
from employee
Case不但能夠在Select子句中使用,在From子句和Where子句中同樣可以使用。下面是在Where子句中使用的一個(gè)例子:
select empno, sex, age
from employee
where
case sex
when 'M' then 55
when 'F' then 50
end > age
在From子句中使用的例子極為少見(jiàn),下面是一個(gè)極端的例子。在合同表ctrct_list、客戶表customer和訂單表quote中都有合同號(hào)字段,但訂單表中的合同號(hào)可能為空。要求查詢出訂單表訂單id和合同號(hào),如訂單表中合同號(hào)為空的話,查出客戶表中相應(yīng)的合同號(hào)。
select distinct
q.quote_id,
case rtrim(coalesce(q.ctrct_num, ''))
when '' then rtrim(coalesce(c.ctrct_num, ''))
else rtrim(coalesce(q.ctrct_num, ''))
end ctrct_num
from
(quote q
left outer join customer c
on?q.sold_to_cust_num = c.cust_num)
inner join ctrct_list cl
on?cl.cust_num = q.sold_to_cust_num
and cl.ctrct_num = (
case rtrim(coalesce(q.ctrct_num, ''))
when '' then c.ctrct_num
else q.ctrct_num
end
)
有時(shí)讓SQL語(yǔ)句有條件的執(zhí)行也可以不使用case。下面是一個(gè)例子:
select *
from EMPLOYEE
WHERE
((job='MANAGER') AND vMgrFlag=1)
or
((job='DESIGNER' or job='ANALYST') AND vTechFlag =1)
or
((job='CLERK' or job='OPERATOR') AND vOfficeFlag=1)
此SQL可以要求根據(jù)標(biāo)志位的不同選擇出不同類型的雇員。各個(gè)標(biāo)志位在執(zhí)行SQL前應(yīng)提前設(shè)置好。這種方法可以在某些情況下將動(dòng)態(tài)SQL改寫(xiě)為靜態(tài)SQL,因此在編寫(xiě)存儲(chǔ)過(guò)程時(shí)非常實(shí)用。但要指出的是,DB2的查詢優(yōu)化器不可能將這種SQL也優(yōu)化得非常高效,因此在數(shù)據(jù)量比較大時(shí)可能會(huì)帶來(lái)性能問(wèn)題。開(kāi)發(fā)人員需要在編寫(xiě)完成后使用實(shí)際數(shù)據(jù)測(cè)試,必要的話進(jìn)行性能優(yōu)化。
總結(jié)
以上是生活随笔為你收集整理的db2case语句_DB2 常用的SQL语句的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 斗罗大陆魂师对决千仞雪怎么加点?
- 下一篇: python和anaconda的区别_a