<a>建立和調用 SQL 過程</a>
SQL 過程 是過程體用 SQL 編寫的過程。過程體包含 SQL 過程的邏輯。它可以包含變量聲明、條件處理、流控制語句和 DML。可以在複合語句(compound statement) 中指定多個 SQL 語句,複合語句将幾個語句組合成一個可執行塊。
當成功地調用 <code>CREATE PROCEDURE (SQL)</code> 語句時,就會建立一個 SQL 過程,這會在應用伺服器上定義 SQL 過程。SQL 過程是一種定義比較複雜的查詢或任務的簡便方式,可以在需要時調用它們。
建立 SQL 過程的一種簡便方法是在指令行處理程式(CLP)腳本中編寫 <code>CREATE PROCEDURE (SQL)</code> 語句。例如,如果将下面的語句放在一個稱為 <code>createSQLproc.db2</code> 的檔案中,就可以執行這個檔案來建立 SQL 過程:
連接配接 SAMPLE 資料庫。
發出以下指令:
<code>db2</code> 指令指定 <code>-td</code> 選項标志,這讓指令行處理程式使用 <code>@</code> 作為語句終止字元(因為在過程體内已經使用分号作為語句終止字元);<code>-v</code> 選項标志讓指令行處理程式将指令文本回顯到标準輸出;<code>-f</code> 選項标志讓指令行處理程式從指定的檔案(而不是标準輸入)讀取指令輸入。
這個過程稱為 SALES_STATUS,它接受一個輸入參數 quota 并傳回輸出參數 sql_state。過程體中隻有一個 <code>SELECT</code> 語句,它傳回銷售總量超過指定額度的銷售人員的姓名和銷售總量。
大多數 SQL 過程接受至少一個輸入參數。在我們的示例中,輸入參數包含一個值(quota),這個值用在過程體包含的 <code>SELECT</code> 語句中。
許多 SQL 過程傳回至少一個輸出參數。我們的示例包含一個輸出參數(sql_state),這個參數用來報告 SQL 過程是成功還是失敗。DB2 傳回一個 <code>SQLSTATE</code> 值來響應條件,可以作為 SQL 語句的結果。因為傳回的 <code>SQLCODE</code> 或 <code>SQLSTATE</code> 值屬于過程體中發出的最後一個 SQL 語句,而且通路這些值會改變這些變量的後續值(因為通路它們需要使用 SQL 語句),是以應該将 <code>SQLCODE</code> 或 <code>SQLSTATE</code> 值指派給一個局部定義的變量并通過它傳回(比如我們示例中的 sql_state 變量)。
SQL 過程的參數清單可以指定零個或更多的參數,每個參數可以是三種類型之一:
<code>IN</code> 參數将一個輸入值傳遞給 SQL 過程;在過程體内不能修改這個值。
<code>OUT</code> 參數從 SQL 過程傳回一個輸出值。
<code>INOUT</code> 參數将一個輸入值傳遞給 SQL 過程并從 SQL 過程傳回一個輸出值。
SQL 過程可以傳回零個或更多的結果集。在我們的示例中,SALES_STATUS 過程傳回一個結果集。傳回結果集的方法是:
在 <code>DYNAMIC RESULT SETS</code> 子句中聲明 SQL 過程傳回的結果集數量。
在過程體中為傳回的每個結果集聲明一個遊标(使用 <code>WITH RETURN FOR</code> 子句)。遊标(cursor) 是一個命名的控制結構,應用程式使用它指向有序行集中的特定行。遊标用來從行集中檢索行。
打開傳回的每個結果集的遊标。
當 SQL 過程傳回時,讓遊标打開着。
變量必須在 SQL 過程體的開頭進行聲明。要聲明 一個變量,應該配置設定一個惟一的辨別符并指定變量的 SQL 資料類型,還可以可選地配置設定一個初始值。
我們的 SQL 過程示例中的 <code>SET</code> 子句是一個流控制 子句。在 SQL 過程體中可以使用以下的流控制語句、結構和子句來進行有條件處理:
<code>CASE</code> 結構根據對一個或多個條件的計算選擇一個執行路徑。
<code>FOR</code> 結構對于表中的每一行執行一個代碼塊。
<code>GET DIAGNOSTICS</code> 語句将關于前一個 SQL 語句的資訊傳回到一個 SQL 變量中。
<code>GOTO</code> 語句将控制轉移到一個有标簽的塊(一個或多個語句的塊,由一個惟一的 SQL 名稱和冒号來辨別)。
<code>IF</code> 結構根據對條件的計算選擇一個執行路徑。<code>ELSEIF</code> 和 <code>ELSE</code> 子句允許執行分支,或指定在其他條件不滿足時執行的預設操作。
<code>ITERATE</code> 子句将流控制傳遞到一個有标簽的循環的開頭。
<code>LEAVE</code> 子句使程式控制離開一個循環或代碼塊。
<code>LOOP</code> 子句多次執行一個代碼塊,直到 <code>LEAVE</code>、<code>ITERATE</code> 或 <code>GOTO</code> 語句使控制離開循環。
<code>REPEAT</code> 子句重複執行一個代碼塊,直到指定的搜尋條件傳回真為止。
<code>RETURN</code> 子句将控制從 SQL 過程傳回給調用者。
<code>SET</code> 子句将一個值指派給一個輸出變量或 SQL 變量。
<code>WHILE</code> 在指定的條件為真時重複執行一個代碼塊。
使用 SQL <code>CALL</code> 語句從 DB2 指令行調用 SQL 過程。被調用的過程必須在系統編目中進行定義。用任何支援的語言編寫的客戶機應用程式都可以調用 SQL 過程。為了調用 SQL 過程 SALES_STATUS,執行以下步驟:
發出以下語句:
因為圓括号對于基于 UNIX 的系統上的指令 shell 有特殊意義,是以在這些系統上必須在它們前面加上反斜線(<code>\</code>)字元,或者用雙引号包圍它們:
如果以互動輸入模式使用指令行處理程式(CLP)(由 <code>db2 =></code> 輸入提示表示),那麼不必包含雙引号。
在這個示例中,值 25 作為輸入參數 quota 傳遞給 SQL 過程,并使用問号(?)作為輸出參數 sql_state 的占位符。這個過程傳回銷售總量超過指定額度(25)的每個銷售人員的姓名和銷售總量。下面是這個語句傳回的輸出示例:
SQL_STATE: 00000
SALES_PERSON
TOTAL_SALES
GOUNOT
50
LEE
91
"SALES_STATUS" RETURN_STATUS: "0"

<a href="https://www6.software.ibm.com/developerworks/cn/education/db2/db2-cert7304/section5.html#main">回頁首</a>
<a>建立和使用 SQL 使用者定義函數</a>
可以建立使用者定義函數來擴充内置的 DB2 函數。例如,建立計算複雜的算術表達式或操作字元串的函數,然後在 SQL 語句中像對待任何現有的内置函數一樣引用這些函數。
假設需要一個傳回圓的面積的函數,這個函數的輸入參數是圓的半徑。内置的 DB2 函數中沒有這樣的函數,但是可以建立一個使用者定義的 SQL 标量函數 來執行這個任務,可以在 SQL 語句中支援标量函數的任何地方引用這個函數。
<code>NO EXTERNAL ACTION</code> 子句指出這個函數不會對資料庫管理程式不管理的對象的狀态有任何影響。<code>DETERMINISTIC</code> 關鍵字指出這個函數對于給定的參數值總是傳回相同的結果。在查詢優化期間會使用這個資訊。執行這個函數的簡便方法是在一個查詢中引用它。在下面的示例中,針對 <code>SYSIBM.SYSDUMMY1</code> 編目視圖(其中隻有一行)執行這個查詢(可以選擇任意的查詢目标):
還可以建立使用者定義的表函數,它接受零個或更多的輸入參數并以表的形式傳回資料。表函數隻能用在 SQL 語句的 <code>FROM</code> 子句中。
假設需要一個傳回擁有特定工作的所有職員的姓名和職員号的函數,函數的參數是這個工作的頭銜。下面是執行這個任務的表函數示例:
以下查詢在 <code>FROM</code> 子句中引用這個新的表函數,并傳遞工作頭銜 ‘CLERK’ 作為函數的參數。文法要求用關鍵字 <code>AS</code> 引入一個相關名稱:
本文轉自tiasys部落格園部落格,原文連結:http://www.cnblogs.com/tiasys/archive/2009/02/27/1399361.html,如需轉載請自行聯系原作者