日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

系統(tǒng) 4255 0
DB2 提供的強(qiáng)大功能可以讓<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">開(kāi)發(fā)</nobr>人員創(chuàng)建出非常高效穩(wěn)定的存儲(chǔ)過(guò)程。但對(duì)于初學(xué)者來(lái)說(shuō),開(kāi)發(fā)出這樣的程序并不容易。本文主要討論開(kāi)發(fā)高效穩(wěn)定的 DB2 <nobr oncontextmenu="return false;" onmousemove="kwM(6);" id="key5" onmouseover="kwE(event,6, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程的一些常用技巧和方法。

  讀者定位為具有一定開(kāi)發(fā)經(jīng)驗(yàn)的 DB2 開(kāi)發(fā)經(jīng)驗(yàn)的開(kāi)發(fā)人員。

  讀者可以從本文學(xué)習(xí)到如何編寫(xiě)穩(wěn)定、高效的存儲(chǔ)過(guò)程。并可以直接使用文章中提供的 DB2 代碼,從而節(jié)省他們的開(kāi)發(fā)和調(diào)試時(shí)間,<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">提高</nobr>效率。

  本文以 DB2 開(kāi)發(fā)人員的角度介紹了在 DB2 存儲(chǔ)過(guò)程開(kāi)發(fā)中需要注意的事項(xiàng)和技巧。新手如果能夠按照本文介紹的最佳實(shí)踐來(lái)開(kāi)發(fā)存儲(chǔ)過(guò)程,可以避免一些常見(jiàn)的錯(cuò)誤,從而編寫(xiě)出高效的程序。本文從初始化參數(shù)、游標(biāo)、異常處理、臨時(shí)表的使用以及如何<nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">尋找</nobr>并 rebind 非法存儲(chǔ)過(guò)程等常見(jiàn)問(wèn)題進(jìn)行了著重討論,并且給出了示例代碼。

  在存儲(chǔ)過(guò)程中,開(kāi)發(fā)人員能夠聲明和設(shè)置 SQL 變量、實(shí)現(xiàn)流程<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">控制</nobr>、處理異常、能夠?qū)?shù)據(jù)進(jìn)行插入、更新或者刪除。同時(shí),客戶(hù)應(yīng)用(這里指調(diào)用存儲(chǔ)過(guò)程的應(yīng)用程序,它可以是 JDBC 的調(diào)用,也可以是 ODBC 和 CLI 等)和存儲(chǔ)過(guò)程之間可以傳遞參數(shù),并且從存儲(chǔ)過(guò)程中返回結(jié)果集。其中,使用 SQL 編寫(xiě)的 DB2 存儲(chǔ)過(guò)程是在開(kāi)發(fā)中常見(jiàn)的一種存儲(chǔ)過(guò)程。本文主要討論此類(lèi)存儲(chǔ)過(guò)程。

  最佳實(shí)踐 1:在創(chuàng)建存儲(chǔ)過(guò)程語(yǔ)句中提供必要的參數(shù)

  創(chuàng)建存儲(chǔ)過(guò)程語(yǔ)句(CREATE PROCEDURE)可以包含很多參數(shù),雖然從語(yǔ)法角度講它們不是必須的,但是在創(chuàng)建存儲(chǔ)過(guò)程時(shí)提供它們可以提高執(zhí)行<nobr oncontextmenu="return false;" onmousemove="kwM(5);" id="key4" onmouseover="kwE(event,5, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">效率</nobr>。下面是一些常用的參數(shù)

  容許 SQL (allowed-SQL)

  容許 SQL (allowed-SQL)子句的值指定了存儲(chǔ)過(guò)程是否會(huì)使用 SQL 語(yǔ)句,如果使用,其類(lèi)型如何。它的可能值如下所示:

  NO SQL: 表示存儲(chǔ)過(guò)程不能夠執(zhí)行任何 SQL 語(yǔ)句。

CONTAINS SQL: 表示<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程可以執(zhí)行 SQL 語(yǔ)句,但不會(huì)讀取 SQL 數(shù)據(jù),也不會(huì)修改 SQL 數(shù)據(jù)。

  READS SQL DATA: 表示在存儲(chǔ)過(guò)程中包含不會(huì)修改 SQL <nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">數(shù)據(jù)</nobr>的 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。不同類(lèi)型的存儲(chǔ)過(guò)程執(zhí)行的效率是不同的,其中 NO SQL 效率最好,MODIFIES SQL DATA 最差。如果存儲(chǔ)過(guò)程只是讀取數(shù)據(jù),但是因?yàn)闆](méi)有聲明 allowed-SQL 使其被當(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。

  返回結(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ù)量(number-of-result-sets)。如果這里聲明的返回結(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é)果集,<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">提高</nobr>了程序的完整性。

  最佳實(shí)踐 2:對(duì)輸入?yún)?shù)進(jìn)行必要的的檢查和預(yù)處理

  無(wú)論使用哪種編程語(yǔ)言,對(duì)輸入<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key4" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">參數(shù)</nobr>的判斷都是必須的。正確的參數(shù)驗(yàn)證是保證程序良好運(yùn)行的前提。同樣的,在 DB2 中對(duì)輸入?yún)?shù)的驗(yàn)證和處理也是很重要的。正確的驗(yàn)證和預(yù)處理操作包括:

如果輸入?yún)?shù)錯(cuò)誤,<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key3" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程應(yīng)返回一個(gè)明確的值告訴客戶(hù)應(yīng)用,然后客戶(hù)應(yīng)用可以根據(jù)返回的值進(jìn)行處理,或者向存儲(chǔ)過(guò)程提交新的參數(shù),或者去調(diào)用其他的程序。

  根據(jù)<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">業(yè)務(wù)</nobr>邏輯,對(duì)輸入?yún)?shù)作一定的預(yù)處理,如大小寫(xiě)的轉(zhuǎn)換,NULL 與空字符串或 0 的轉(zhuǎn)換等。

  在 DB2 儲(chǔ)存過(guò)程<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">開(kāi)發(fā)</nobr>中,如需要遇到對(duì)空(NULL)進(jìn)行初始化,我們可以使用 COALESCE 函數(shù)。COALESCE函數(shù)返回第一個(gè)非空的參數(shù),語(yǔ)法如下:

  清單1:COALESCE 函數(shù)

                 .---------------.
      (1)         V        |
>>-COALESCE-------(--expression----,--expression-+--)----------><

  COALESCE函數(shù)會(huì)依次檢查輸入的參數(shù),返回第一個(gè)不是NULL的參數(shù),只有當(dāng)傳入COALESCE函數(shù)的所有的參數(shù)都是NULL的時(shí)候,函數(shù)才會(huì)返回NULL。例如, COALESCE(piName,''),如果變量piName為NULL,那么函數(shù)會(huì)返回'',否則就會(huì)返回piName本身的值。

  下面的例子展示了如何對(duì)參數(shù)進(jìn)行檢查何初始化。

  Person表用來(lái)存儲(chǔ)個(gè)人的基本信息,其定義如下:

  表1: Person

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

  下面是用于向表Person插入<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">數(shù)據(jù)</nobr>的存儲(chǔ)過(guò)程的參數(shù)預(yù)處理部分代碼:

  SET poGenStatus = 0;       

  SET piName  = RTRIM(COALESCE(piName, ''));
  SET piRank = COALESCE(piRank, 0);

  -- make sure all required input parameters are not null
  IF ( piNum IS NULL       
     OR piName = ''   
     OR piAge IS NULL ) 
  THEN               
    SET poGenStatus = 34100;   
    RETURN poGenStatus;     
  END IF;    

表Person中num、name和age都是非空字段。對(duì)于name字段,多個(gè)空格我們也認(rèn)為是空值,所以在進(jìn)行判斷前我們調(diào)用RTRIM和COALESCE對(duì)其進(jìn)行處理,然后使用 piName = '',對(duì)其進(jìn)行非空判斷;對(duì)于Rank字段,我們希望如果用戶(hù)輸入的NULL,我們把它設(shè)置成"0",對(duì)其我們也使用COALESCE進(jìn)行初始化;對(duì)于"Age"和"Num" 我們直接使用 IS NULL進(jìn)行非空判斷就可以了。

  如果輸入?yún)?shù)沒(méi)有通過(guò)非空判斷,我們就對(duì)輸出參數(shù)poGenStatus設(shè)置一個(gè)確定的值(例子中為 34100)告知調(diào)用者:輸入?yún)?shù)錯(cuò)誤。

  下面是對(duì)參數(shù)初始化規(guī)則的一個(gè)總結(jié),供大家參考:

  1. 輸入?yún)?shù)為字符類(lèi)型,且允許為空的,可以使用COALESCE(inputParameter,'')把NULL轉(zhuǎn)換成'';

  2. 輸入類(lèi)型為整型,且允許為空的,可以使用COALESCE(inputParameter,0),把空轉(zhuǎn)換成0;

  3. 輸入?yún)?shù)為字符類(lèi)型,且是非空非空格的,可以使用COALESCE(inputParameter,'')把NULL轉(zhuǎn)換成'',然后判斷函數(shù)返回值是否為'';

  4. 輸入類(lèi)型為整型,且是非空的,不需要使用COALESCE函數(shù),直接使用IS NULL進(jìn)行非空判斷。

  最佳實(shí)踐 3:正確設(shè)定游標(biāo)的返回類(lèi)型

  前面我們已經(jīng)討論了如何聲明存儲(chǔ)過(guò)程的返回結(jié)果集。這里我們討論一下結(jié)果集返回類(lèi)型的問(wèn)題。結(jié)果集的返回類(lèi)型有兩種:調(diào)用者(CALLER) 和客戶(hù)應(yīng)用(CLIENT)。首先我們看一下聲明這兩種游標(biāo)的例子:

CREATE PROCEDURE getPeople(IN piAge INTEGER)
DYNAMIC RESULT SETS 2
READS SQL DATA
LANGUAGE SQL
BEGIN
  DECLARE rs1 CURSOR WITH RETURN TO CLIENT FOR
    SELECT name, age FROM person
      WHERE age<piAge;
  DECLARE rs2 CURSOR WITH RETURN TO CALLER FOR
    SELECT NAME, age FROM person
      WHERE age>piAge;      
  OPEN rs1;
  OPEN rs2;
END  

代碼中rs1游標(biāo)的DECLAER語(yǔ)句中包含WITH RETURN TO CLIENT子句,表示結(jié)果集返回給<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">客戶(hù)</nobr>應(yīng)用(CLIENT)。rs2游標(biāo)的DECLARE語(yǔ)句中包含WITH RETURN TO CALLER子句,表示結(jié)果集返回給調(diào)用者(CALLER)。

  游標(biāo)返回給調(diào)用者(CALLER)表示由<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程的調(diào)用者接收結(jié)果集,而不考慮調(diào)用者是否是另一個(gè)存儲(chǔ)過(guò)程,還是客戶(hù)<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key4" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">應(yīng)用</nobr>。圖(1)中存儲(chǔ)過(guò)程PROZ如果聲明為WITH RETURN TO CALLER,那么結(jié)果集會(huì)返回給存儲(chǔ)過(guò)程PROY,Client Application是不會(huì)得到PROZ返回的結(jié)果集的。

  圖1:存儲(chǔ)過(guò)程遞歸調(diào)用

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

  游標(biāo)返回給客戶(hù)應(yīng)用(CLIENT)表示由發(fā)出最初 CALL 語(yǔ)句的客戶(hù)應(yīng)用接收結(jié)果集,即使結(jié)果集由嵌套層次中的 15 層深的嵌套存儲(chǔ)過(guò)程發(fā)出也是如此。圖1中存儲(chǔ)過(guò)程 PROZ 如果聲明為 WITH RETURN TO CLIENT,那么結(jié)果集會(huì)返回給 Client Application。返回給客戶(hù)應(yīng)用(CLIENT)的游標(biāo)聲明是我們經(jīng)常使用的,也是默認(rèn)的結(jié)果集類(lèi)型。

  在聲明返回類(lèi)型時(shí),我們要認(rèn)真考慮一下,我們需要把結(jié)果集返回給誰(shuí),以免丟失返回集,導(dǎo)致程序錯(cuò)誤。

  最佳<nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">實(shí)踐</nobr> 4:異常(condition)處理

  在存儲(chǔ)過(guò)程執(zhí)行的過(guò)程中,經(jīng)常因?yàn)?lt;nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">數(shù)據(jù)</nobr>或者其他問(wèn)題產(chǎn)生異常(condition)。根據(jù)業(yè)務(wù)邏輯,存儲(chǔ)過(guò)程應(yīng)該對(duì)異常進(jìn)行相應(yīng)處理或直接返回給調(diào)用者。此處暫且將condition譯為異常以方便讀者理解。實(shí)際上有些異常(condition)并非是由于錯(cuò)誤引起的,下面將詳細(xì)講述。

  當(dāng)存儲(chǔ)過(guò)程中的語(yǔ)句返回的SQLSTATE值超過(guò)00000的時(shí)候,就表明在存儲(chǔ)過(guò)程中產(chǎn)生了一個(gè)異常(condition),它表示出現(xiàn)了錯(cuò)誤、數(shù)據(jù)沒(méi)有找到或者出現(xiàn)了警告。為了響應(yīng)和處理存儲(chǔ)過(guò)程中出現(xiàn)的異常,我們必須在存儲(chǔ)過(guò)程體中聲明異常處理器(condition handler),它可以決定存儲(chǔ)過(guò)程怎樣響應(yīng)一個(gè)或者多個(gè)已定義的異常或者預(yù)定義異常組。聲明條件處理器的語(yǔ)法如下,它會(huì)位于變量聲明和游標(biāo)聲明之后:

清單4:聲明異常處理器

DECLARE handler-type HANDLER FOR condition handler-action

  異常處理器類(lèi)型(handler-type)有以下幾種:

  CONTINUE 在處理器操作完成之后,會(huì)繼續(xù)執(zhí)行產(chǎn)生這個(gè)異常語(yǔ)句之后的下一條語(yǔ)句。

  EXIT 在處理器操作完成之后,存儲(chǔ)過(guò)程會(huì)終止,并將<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">控制</nobr>返回給調(diào)用者。

  UNDO 在處理器操作執(zhí)行之前,DB2會(huì)回滾存儲(chǔ)過(guò)程中執(zhí)行的SQL操作。在處理器操作完成之后,<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程會(huì)終止,并將控制返回給調(diào)用者。

  異常處理器可以處理基于特定SQLSTATE值的定制異常,或者處理<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">預(yù)定</nobr>義異常的類(lèi)。預(yù)定義的3種異常如下所示:

  NOT FOUND 標(biāo)識(shí)導(dǎo)致SQLCODE值為+100或者SQLSATE值為02000的異常。這個(gè)異常通常在SELECT沒(méi)有返回行的時(shí)候出現(xiàn)。

  SQLEXCEPTIOIN 標(biāo)識(shí)導(dǎo)致SQLCODE值為負(fù)的異常。

  SQLWARNING 標(biāo)識(shí)導(dǎo)致警告異常或者導(dǎo)致+100以外的SQLCODE正值的異常。

  如果產(chǎn)生了NOT FOUND 或者SQLWARNING異常,并且沒(méi)有為這個(gè)異常定義異常處理器,那么就會(huì)忽略這個(gè)異常,并且將控制流轉(zhuǎn)向下一個(gè)語(yǔ)句。如果產(chǎn)生了SQLEXCEPTION異常,并且沒(méi)有為這個(gè)異常定義異常處理器,那么存儲(chǔ)過(guò)程就會(huì)失敗,并且會(huì)將控制流返回調(diào)用者。

  以下示例聲明了兩個(gè)異常處理器。 EXIT處理器會(huì)在出現(xiàn)SQLEXCEPTION 或者SQLWARNING異常的時(shí)候被調(diào)用。EXIT處理器會(huì)在終止SQL程序之前,將名為stmt的變量設(shè)為"ABORTED",并且將控制流返回給調(diào)用者。UNDO處理器會(huì)將控制流返回給調(diào)用者之前,回滾存儲(chǔ)過(guò)程體中已經(jīng)完成的SQL操作。

  清單5:異常處理器示例

DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
    SET stmt = 'ABORTED';

DECLARE UNDO HANDLER FOR NOT FOUND;

如果預(yù)定義異常集不能滿(mǎn)足需求,就可以為特定的SQLSTATE值聲明定制異常,然后再為這個(gè)定制異常聲明處理器。語(yǔ)法如下:

  清單6:定制異常處理器

DECLARE unique-name CONDITION FOR SQLSATE 'sqlstate'

  處理器可以由單獨(dú)的<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程語(yǔ)句定義,也可以使用由BEGIN…END塊界定的復(fù)合語(yǔ)句定義。注意在執(zhí)行符合語(yǔ)句的時(shí)候,SQLSATE和SQLCODE的值會(huì)被改變,如果需要保留異常前的SQLSATE和SQLCODE,就需要在執(zhí)行復(fù)合語(yǔ)句的第一個(gè)語(yǔ)句把SQLSATE和SQLCODE賦予本地變量或<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key2" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">參數(shù)</nobr>。

  通常,我們會(huì)為存儲(chǔ)過(guò)程定義一個(gè)執(zhí)行狀態(tài)的輸出參數(shù)(例如:poGenStatus)。

  根據(jù)這個(gè)輸出狀態(tài),可以表明存儲(chǔ)過(guò)程是否正確執(zhí)行完畢。我們需要定義一些異常處理器為這個(gè)輸出參數(shù)賦值。下面是一個(gè)例子:

  清單7:定義為輸出參數(shù)賦值的異常處理器

 -- Generic Handler        
  DECLARE CONTINUE HANDLER FOR SQLEXCEPTION, SQLWARNING, NOT FOUND
  BEGIN NOT ATOMIC         
   -- Capture SQLCODE & SQLSTATE 
   SELECT SQLCODE, SQLSTATE   
   INTO  hSqlcode, hSqlstate  
   FROM  SYSIBM.SYSDUMMY1;   

   -- Use the poGenStatus variable to tell the procedure -- what type of
   error occurred      
   CASE hSqlstate         
    WHEN '02000' THEN      
     SET poGenStatus=5000;   
    WHEN '42724' THEN      
     SET poGenStatus=3;     
    ELSE             
     IF (hSqlCode < 0) THEN   
      SET poGenStatus=hSqlCode;
     END IF;          
    END CASE;           
  END;

上面的異常處理器會(huì)在出現(xiàn)SQLEXCEPTION, SQLWARNING, NOT FOUND異常的時(shí)候觸發(fā)。異常處理器會(huì)取出當(dāng)前的SQLCODE, SQLSTATE,然后根據(jù)它們的值來(lái)設(shè)置輸出<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: 0px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">參數(shù)</nobr>(poGenStatus)的值。

  我們還可以定制一些異常處理器。例如,我們可以定義一些對(duì)參數(shù)進(jìn)行初始化的異常處理器。這里,異常處理器可以看作是一個(gè)供<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程自己調(diào)用的內(nèi)部函數(shù)。下面是這種情況的一個(gè)例子:

  清單8:供存儲(chǔ)過(guò)程自己調(diào)用的內(nèi)部函數(shù)

  -----------------------------------------------------
  -- CONDITION declaration     
  -----------------------------------------------------
  -- (80100~80199) SQLCODE & SQLSTATE
  DECLARE sqlReset CONDITION for sqlstate '80100';

  -----------------------------------------------------
  -- EXCEPTION HANDLER declaration 
  -----------------------------------------------------
  -- Handy Handler         
  DECLARE CONTINUE HANDLER FOR sqlReset
  BEGIN NOT ATOMIC         
   SET hSqlcode  = 0;      
   SET hSqlstate = '00000';   
   SET poGenStatus = 0;      
  END;               
            …………     
  -----------------------------------------------------
  -- Procedure Body        
  -----------------------------------------------------
  SIGNAL sqlreset;

  -- insert the record 
             …………

上面定制的異常處理器負(fù)責(zé)對(duì)參數(shù)hSqlcode,hSqlstate和poGenStatus初始化。當(dāng)我們?cè)诔绦蛑行枰獙?duì)它們初始化時(shí),我們只需要調(diào)用SIGNAL sqlreset就可以了。

  最佳實(shí)踐 5:合理使用臨時(shí)表

  我們?cè)趦?chǔ)存過(guò)程<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">開(kāi)發(fā)</nobr>中經(jīng)常使用臨時(shí)表。合理的使用臨時(shí)表可以簡(jiǎn)化程序的編寫(xiě),提供執(zhí)行效率,然而濫用臨時(shí)表同樣也會(huì)使得程序運(yùn)行效率降低。

  臨時(shí)表一般在如下情況下使用:

  1. 臨時(shí)表用于<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>程序運(yùn)行中的臨時(shí)數(shù)據(jù)。例如,如果在一個(gè)程序中第一條查詢(xún)語(yǔ)句執(zhí)行的結(jié)果會(huì)被后續(xù)的查詢(xún)語(yǔ)句用到,那么我們可以把第一次查詢(xún)的結(jié)果存儲(chǔ)在一個(gè)臨時(shí)表中供后續(xù)查詢(xún)語(yǔ)句使用,而不是在后續(xù)查詢(xún)語(yǔ)句中重新查詢(xún)一次。如果第一條查詢(xún)語(yǔ)句非常復(fù)雜和耗時(shí),那么上面的策略是非常有效的。

  2. 臨時(shí)表可以用于存儲(chǔ)在一個(gè)程序中需要返回多次的結(jié)果集。例如,程序中有一個(gè)很耗資源的多表查詢(xún),同時(shí),該查詢(xún)?cè)诔绦蛑行枰獔?zhí)行多次,那么就可以把第一次查詢(xún)的結(jié)果集存儲(chǔ)在臨時(shí)保中,后續(xù)的查詢(xún)只需要查臨時(shí)表就可以了。

  3. 臨時(shí)表也可以用于讓SQL訪問(wèn)非關(guān)系型<nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">數(shù)據(jù)庫(kù)</nobr>。例如,可以編寫(xiě)程序把非關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)插入到一個(gè)全局臨時(shí)表中,那么我們就可以對(duì)其數(shù)據(jù)進(jìn)行查詢(xún)。

  我們可使用 DECLARE GLOBAL TEMPORARY TABLE 語(yǔ)句來(lái)定義臨時(shí)表。DB2的臨時(shí)表是基于會(huì)話(huà)的,且在會(huì)話(huà)之間是隔離的。當(dāng)會(huì)話(huà)結(jié)束時(shí),臨時(shí)表的數(shù)據(jù)被刪除,臨時(shí)表被隱式卸下。對(duì)臨時(shí)表的定義不會(huì)在SYSCAT.TABLES中出現(xiàn) 下面是定義臨時(shí)表的一個(gè)示例:

  清單9:定義臨時(shí)表

DECLARE GLOBAL TEMPORARY TABLE gbl_temp
LIKE person
ON COMMIT DELETE ROWS
NOT LOGGED
IN usr_tbsp

  此語(yǔ)句創(chuàng)建一個(gè)名為 gbl_temp 的用戶(hù)臨時(shí)表。定義此用戶(hù)臨時(shí)表 所使用的列的名稱(chēng)和說(shuō)明與 person 的列的名稱(chēng)和說(shuō)明完全相同。

清單10:創(chuàng)建有兩個(gè)字段的臨時(shí)表

DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP2
  (
    ID  INTEGER default 3,
    NAME CHAR(30)    
  )
  --WITH REPLACE
  NOT LOGGED;
  --IN USER_TEMP_01;

  此語(yǔ)句創(chuàng)建了一個(gè)有兩個(gè)字段的臨時(shí)表。

  理論上臨時(shí)表是不需要<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">顯示</nobr>DROP的,因?yàn)樗腔跁?huì)話(huà)的,當(dāng)臨時(shí)表基于的連接關(guān)閉的時(shí)候,臨時(shí)表也就不存在了。但是在實(shí)際<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">開(kāi)發(fā)</nobr>中會(huì)有一些情況需要我們對(duì)臨時(shí)表加以注意。

  一種情況就是被調(diào)用的存儲(chǔ)過(guò)程的返回值是一個(gè)基于臨時(shí)表的結(jié)果集。當(dāng)<nobr oncontextmenu="return false;" onmousemove="kwM(5);" id="key5" onmouseover="kwE(event,5, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程執(zhí)行完畢的時(shí)候,臨時(shí)表并不會(huì)消失,因?yàn)榉祷氐慕Y(jié)果集相當(dāng)于一個(gè)指針,指向臨時(shí)表所在的<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key4" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">內(nèi)存</nobr>地址,此時(shí)臨時(shí)表是不會(huì)被DROP掉的。這種情況下,既不能在存儲(chǔ)過(guò)程中刪除這個(gè)臨時(shí)表,也不應(yīng)該由客戶(hù)<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">應(yīng)用</nobr>顯示的刪除臨時(shí)表,這就容易出現(xiàn)一些問(wèn)題。下面我們通過(guò)一個(gè)例子來(lái)說(shuō)明這個(gè)問(wèn)題。

  下面示例代碼是返回臨時(shí)表的存儲(chǔ)過(guò)程(get_temp_table):

  清單11:返回臨時(shí)表的存儲(chǔ)過(guò)程

  -----------------------------------------------------
  -- TEMPORARY TABLE & CURSOR declaration
  -----------------------------------------------------
  DECLARE GLOBAL TEMPORARY TABLE SESSION.TEMP
  (
    ID     INTEGER,
    NAME   CHAR(30)    
  )
  --WITH REPLACE
  NOT LOGGED;

  P2: BEGIN

  DECLARE R_CRSR CURSOR WITH RETURN TO CLIENT FOR
  SELECT * FROM SESSION.TEMP
  FOR READ ONLY;

  INSERT INTO SESSION.TEMP VALUES(1,piName);

  OPEN R_CRSR;

  END P2;

存儲(chǔ) 過(guò)程中聲明了有兩個(gè)字段的臨時(shí)表TEMP,聲明了一個(gè)游標(biāo)R_CRSR返回臨時(shí)表中所有<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">記錄</nobr>,最后在臨時(shí)表中插入兩條記錄。

  程序第一次執(zhí)行的結(jié)果如下:

  圖2:程序第一次執(zhí)行的結(jié)果

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

  可以從圖中看出,運(yùn)行結(jié)果是我們期望的。那么如果我們?cè)龠\(yùn)行一次,會(huì)有什么結(jié)果呢?下圖是其運(yùn)行結(jié)果:

  圖3:程序再次執(zhí)行的結(jié)果

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

  第二次執(zhí)行的時(shí)候程序卻出錯(cuò)了,這是因?yàn)樵谕粋€(gè)連接中,臨時(shí)表并沒(méi)有被DROP掉,所以在第二次調(diào)用存儲(chǔ)過(guò)程的時(shí)候就會(huì)出現(xiàn)臨時(shí)表已經(jīng)存在的錯(cuò)誤。

  另外一種情況,就是很多時(shí)候例如在websphere中通過(guò)JDBC連接<nobr oncontextmenu="return false;" onmousemove="kwM(4);" id="key4" onmouseover="kwE(event,4, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">數(shù)據(jù)</nobr>庫(kù)時(shí)使用了連接池的技術(shù),這帶來(lái)了一些效率的提升,同時(shí)在某些情況下也容易讓人誤解。客戶(hù)<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">應(yīng)用</nobr>程序中關(guān)閉了數(shù)據(jù)庫(kù)連接,但是并不一定真正關(guān)閉了數(shù)據(jù)庫(kù)連接,如果客戶(hù)應(yīng)用程序使用了臨時(shí)表而數(shù)據(jù)庫(kù)連接并沒(méi)有關(guān)閉,那么臨時(shí)表就不會(huì)被DROP。當(dāng)連接池把這個(gè)連接分給另一個(gè)客戶(hù)程序的時(shí)候,新的客戶(hù)程序仍然可以使用舊的臨時(shí)表,這不是我們希望的。如果想避免上述問(wèn)題,可以在創(chuàng)建臨時(shí)表時(shí),加上WITH REPLACE;或者根據(jù)<nobr oncontextmenu="return false;" onmousemove="kwM(3);" id="key3" onmouseover="kwE(event,3, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">業(yè)務(wù)</nobr>邏輯在合適的地方顯示的DROP臨時(shí)表。

  下面是使用WITH REPLACE創(chuàng)建臨時(shí)表的執(zhí)行情況。

  圖4:使用WITH REPLACE創(chuàng)建臨時(shí)表

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐

  可以看出在一個(gè)連接里面,多次調(diào)用<nobr oncontextmenu="return false;" onmousemove="kwM(2);" id="key2" onmouseover="kwE(event,2, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">存儲(chǔ)</nobr>過(guò)程get_temp_table,也不會(huì)出現(xiàn)問(wèn)題。臨時(shí)表在某些情況下也是需要避免使用的。大家知道臨時(shí)表是存放在內(nèi)存中的,如果一個(gè)臨時(shí)表有上萬(wàn)或者十幾萬(wàn)條<nobr oncontextmenu="return false;" onmousemove="kwM(0);" id="key0" onmouseover="kwE(event,0, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">記錄</nobr>,同時(shí)程序的并發(fā)數(shù)很大,那么在內(nèi)存中建立的臨時(shí)表耗費(fèi)的資源就很龐大,此時(shí)數(shù)據(jù)庫(kù)的性能會(huì)急劇下降,甚至?xí)?dǎo)致數(shù)據(jù)庫(kù)崩潰。因此,大家在使用臨時(shí)表的時(shí)候,需要考慮它對(duì)資源的耗費(fèi),避免盲目使用臨時(shí)表。

  最佳<nobr oncontextmenu="return false;" onmousemove="kwM(5);" id="key3" onmouseover="kwE(event,5, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">實(shí)踐</nobr> 6:尋找并rebind 非法的存儲(chǔ)過(guò)程

  存儲(chǔ)過(guò)程會(huì)因?yàn)槠渖婕昂鸵玫膶?duì)象發(fā)生了改變而導(dǎo)致其非法(invalid),例如:修改了表結(jié)構(gòu),導(dǎo)致引用該表的存儲(chǔ)過(guò)程非法,或者重新編譯一個(gè)存儲(chǔ)過(guò)程,會(huì)使調(diào)用這個(gè)存儲(chǔ)過(guò)程的父存儲(chǔ)過(guò)程非法。此時(shí)我們需要對(duì)非法的存儲(chǔ)過(guò)程重新編譯(rebind)。但是,對(duì)非法的存儲(chǔ)過(guò)程進(jìn)行rebind的時(shí)候,需要確定其引用的對(duì)象是合法的,否則非法的存儲(chǔ)過(guò)程也不能rebind成功。

  這里我們介紹一下發(fā)現(xiàn)和rebind非法存儲(chǔ)過(guò)程的方法。我們是通過(guò)判斷SYSCAT.routines中VALID字段的值來(lái)查找非法存儲(chǔ)過(guò)程的。下面是查找非法存儲(chǔ)過(guò)程的一段代碼:

  清單12:查找非法存儲(chǔ)過(guò)程

   SELECT
    RTRIM(r.routineschema) || '.' || RTRIM(r.routinename) AS spname ,
' ( '|| RTRIM(r.routineschema) || '.' || 'P'||SUBSTR(CHAR(r.lib_id+10000000),2)||' )'
   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;

  獲得的結(jié)果如下:

  清單13:查找非法存儲(chǔ)過(guò)程的結(jié)果

SPNAME              
----------------------------------
TEST.DEMO_INFO_8    (TEST. P3550884)

  可以使用下面的命令rebind它們

  清單14:Rebind 非法存儲(chǔ)過(guò)程語(yǔ)法

rebind package packagename resolve any@

  Packagename就是查詢(xún)結(jié)果中括號(hào)里的值。例如,如果rebind上面查出來(lái)的存儲(chǔ)過(guò)程。我們只需要執(zhí)行下面語(yǔ)句

  清單15:Rebind 非法存儲(chǔ)過(guò)程

rebind package TEST.P3550884 resolve any@

  當(dāng)然,如果此存儲(chǔ)過(guò)程程序本身有問(wèn)題,需要先修改存儲(chǔ)過(guò)程代碼后再進(jìn)行編譯。

  類(lèi)似的,通過(guò)下面的代碼可以獲得非法的視圖。

  清單16:獲得非法的視圖

SELECT
    RTRIM(viewschema) || '.' || RTRIM(viewname) AS viewname
   FROM
    SYSCAT.views
   WHERE
    valid = 'X'
   ORDER BY
    viewname;

  結(jié)束語(yǔ)

  本文介紹了我們?cè)?DB2 存儲(chǔ)過(guò)程<nobr oncontextmenu="return false;" onmousemove="kwM(1);" id="key1" onmouseover="kwE(event,1, this);" style="COLOR: #6600ff; BORDER-BOTTOM: #6600ff 1px dotted; BACKGROUND-COLOR: transparent; TEXT-DECORATION: underline" onclick="return kwC();" onmouseout="kwL(event, this);" target="_blank">開(kāi)發(fā)</nobr>中經(jīng)常用到的一些技巧。同時(shí)這些技巧也是編寫(xiě)優(yōu)秀存儲(chǔ)過(guò)程的基本要求。本文介紹的一些技巧只是揭開(kāi)了高效使用 DB2 的冰山一角。DB2 為我們提供了豐富和強(qiáng)大的功能。在使用 DB2 的時(shí)候,我們應(yīng)當(dāng)深入理解其原理,找出更多的最佳實(shí)踐與大家分享。

DB2存儲(chǔ)過(guò)程開(kāi)發(fā)最佳實(shí)踐


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 庆安县| 西城区| 玉树县| 文水县| 余江县| 潼南县| 灵台县| 开鲁县| 噶尔县| 航空| 哈尔滨市| 特克斯县| 宁陕县| 德兴市| 湾仔区| 商丘市| 合水县| 汤原县| 美姑县| 敖汉旗| 永吉县| 鹤壁市| 建水县| 改则县| 娱乐| 共和县| 张北县| 启东市| 东源县| 什邡市| 广丰县| 万安县| 梅河口市| 班戈县| 藁城市| 皮山县| 南部县| 建宁县| 措美县| 溧水县| 息烽县|