DB2 V9.5版本中數(shù)據(jù)庫應(yīng)用程序移植的改進
• 支持在過程和調(diào)用過程的應(yīng)用程序中使用 ARRAY 數(shù)據(jù)類型。
• 支持全局變量。全局變量是已命名的內(nèi)存變量,您可以通過 SQL 語句訪問和修改此變量。版本 9.5 支持已創(chuàng)建的會話全局變量,這些變量與特定會話相關(guān)聯(lián)并包含該會話獨有的值。
• 支持其他供應(yīng)商的 SQL 方言。版本 9.5 包含對 DECODE、NVL、LEAST 和 GREATEST 函數(shù)的支持。
數(shù)組數(shù)據(jù)類型
在以前的DB2版本,碰到數(shù)據(jù)集合處理的程序移植,我們只能通過臨時表或游標來處理,這是非常麻煩的。
版本 9.5 支持 ARRAY 集合數(shù)據(jù)類型。您可以在存儲過程和應(yīng)用程序中對它們進行處理,此功能使從其他數(shù)據(jù)庫供應(yīng)商移植已支持數(shù)組的應(yīng)用程序和存儲過程更容易。
您可以使用數(shù)組以在應(yīng)用程序與存儲過程之間更有效率地傳遞數(shù)據(jù)以及存儲和處理 SQL 過程中的瞬態(tài)數(shù)據(jù)集合,而不必使用關(guān)系表。SQL 過程中可用的數(shù)組運算符允許更有效率地存儲和檢索數(shù)據(jù)。
版本 9.5 中對數(shù)組數(shù)據(jù)類型的支持允許您執(zhí)行以下操作:
• 根據(jù)數(shù)組創(chuàng)建用戶定義的類型;例如,CREATE TYPE INT10 AS INTEGER ARRAY[10] 定義最多 10 個整數(shù)值的數(shù)組的類型;
• 在存儲過程和應(yīng)用程序中聲明數(shù)組類型的變量和參數(shù);
• 創(chuàng)建和處理數(shù)組值,數(shù)組處理的基本部分包括數(shù)組構(gòu)造方法、設(shè)置子下標、元素計數(shù)和整理;
• 在 JDBC 和 CLI 應(yīng)用程序與 SQL 和 Java 存儲過程之間來回傳遞數(shù)組;
• 將數(shù)組轉(zhuǎn)換為表(每個表行一個數(shù)組元素)以及將聚集列轉(zhuǎn)換為數(shù)組,以便更容易在數(shù)組與 SQL 之間通過接口進行連接;
• 使用輸入和輸出數(shù)組參數(shù)從命令行處理器調(diào)用過程。
ARRAY 數(shù)據(jù)類型定義:
CREATE TYPE type-name AS data-type ARRAY [integer-constant]
其中:data-type 不支持LONG VARCHAR, LONG VARGRAPHIC, LOB, XML類型, integer-constant 最大值2147483647
與ARRAY相關(guān)的函數(shù):
ARRAY_AGG 將行數(shù)據(jù)集聚集成數(shù)組
UNNEST 將數(shù)組數(shù)據(jù)轉(zhuǎn)成行數(shù)據(jù)
CARDINALITY 返回數(shù)組中的元素號,類型 BIGINT
MAX_CARDINALITY 返回數(shù)組中所含的最大元素號,類型 BIGINT
注意,這些函數(shù)只用于SQL procedure
SELECT T.PHONE, T.ID, T.INDEX FROM UNNEST(PHONES, IDS)
WITH ORDINALITY AS T(PHONE, ID, INDEX)
ORDER BY T.INDEX
Example 1
這個例子包含2個存儲過程, sum 和 main. 存儲過程 main 建立一個含有6個元素(integer)的數(shù)組。傳遞這個數(shù)組給存儲過程sum, 計算出所有元素值的和并返回給調(diào)用存儲過程 main. 存儲過程 sum 說明了array subindexing 和CARDINALITY 函數(shù)的用法.
create type intArray as integer array[100] @
create procedure sum(in numList intArray, out total integer)
begin
declare i, n integer;
set n = CARDINALITY(numList);
set i = 1;
set total = 0;
while (i < n) do
set total = total + numList[i];
set i = i + 1;
end while;
end @
create procedure main(out total integer)
begin
declare numList intArray;
set numList = ARRAY[1,2,3,4,5,6];
call sum(numList, total);
end @
Example 2
這個例子,我們使用2個數(shù)組類型(intArray 和 stringArray),使用一個包含列(id 和 name)的 persons 表。 存儲過程 processPersons 添加3個人到 persons表, 并返回person名字的數(shù)組,按id排序,名字中包含字母 'o'。 3個persons 的 id 和 name 作為數(shù)組元素(ids 和 names)添加到數(shù)組中。這些數(shù)組使用UNNEST 函數(shù),將數(shù)組數(shù)據(jù)以包含2列數(shù)據(jù)的表的表達形式表達,并插入到persons 表中。最后使用ARRAY_AGG函數(shù)將數(shù)據(jù)匯集返回給輸出參數(shù)。
create type intArray as integer array[100] @
create type stringArray as varchar(10) array[100] @
create table persons (id integer, name varchar(10)) @
insert into persons values(2, 'Tom') @
insert into persons values(4, 'Jill') @
insert into persons values(1, 'Joe') @
insert into persons values(3, 'Mary') @
create procedure processPersons(out witho stringArray)
begin
declare ids intArray;
declare names stringArray;
set ids = ARRAY[5,6,7];
set names = ARRAY['Bob', 'Ann', 'Sue'];
insert into persons(id, name) (select T.i, T.n from UNNEST(ids, names) as T(i, n));
set witho = (select array_agg(name order by id)
from persons
where name like '%o%');
end @
Example 3
這個例子說明在java代碼中如何調(diào)用含有數(shù)組參數(shù)的存儲過程,本例子中存儲過程bonus_calculate含有2個輸入?yún)?shù),一個是數(shù)組projs,一個是整形percentage
………
String sql = 'CALL bonus_calculate(?, ?)';
CallableStatement callStmt = con.prepareCall(sql);
// Create an SQL Array
projects[0] = 'AD3111';
projects[1] = 'IF1000';
projects[2] = 'MA2111';
java.sql.Array projectArray=con.createArrayOf('VARCHAR',projects);
// set IN parameters
callStmt.setArray(1, projectArray);
callStmt.setInt(2,percentage);
// call the procedure
callStmt.execute();
…………
CREATE PROCEDURE bonus_calculate (IN projs projects, IN percentage integer)
BEGIN
DECLARE emp_array employees;
DECLARE bonus_array bonus;
SELECT cast(array_agg(employee.empno) AS employees),
cast(array_agg(.10*salary) AS bonus) INTO emp_array,bonus_array
FROM vempprojact, unnest(projs) AS P(id), employee
WHERE P.id=vempprojact.projno AND employee.empno=vempprojact.empno;
INSERT INTO bonus_temp
SELECT T.empno, T.bonus
FROM unnest(emp_array, bonus_array)
WITH ORDINALITY AS T(empno,bonus, idx);
END@
全局變量
在以前的DB2版本,碰到含全局變量處理的移植程序移植,我們只能通過全局臨時表來處理,使用起來非常麻煩。
全局變量改進了 SQL 語句之間的數(shù)據(jù)共享。版本 9.5 引入了全局變量的概念,它們是命名的內(nèi)存變量,可以通過 SQL 語句訪問和修改這些變量。全局變量使您能夠在運行于同一會話(或連接)的不同 SQL 語句之間共享數(shù)據(jù),而不需要應(yīng)用程序邏輯來支持此數(shù)據(jù)傳輸。
應(yīng)用程序不再需要發(fā)出這種語句來將值從一個語句的輸出自變量(如主機變量)復(fù)制到另一個語句的輸入自變量。此外,包含在數(shù)據(jù)庫系統(tǒng)本身中的 SQL 語句(如定義觸發(fā)器和視圖的語句)現(xiàn)在可以訪問此共享信息。
全局變量有助于您為數(shù)據(jù)庫本身中的數(shù)據(jù)傳輸實現(xiàn)更復(fù)雜的交互式模型,以便您不必在應(yīng)用程序或 SQL 過程中放置支持邏輯。與全局變量相關(guān)聯(lián)的已定義特權(quán)確保所傳送數(shù)據(jù)的安全性不會升高到強制通過應(yīng)用程序邏輯。如果安全性存在問題,那么您可以通過 GRANT 和 REVOKE 語句來控制對全局變量的訪問。
存儲靜態(tài)的、在會話期間很少更改的或者進行了管理控制的數(shù)據(jù)時,全局變量特別有用。用于將警報發(fā)送至 DBA 的尋呼機號以及指示是啟用還是禁用某些觸發(fā)器的指示器就是這種數(shù)據(jù)的示例。
版本 9.5 支持已創(chuàng)建的會話全局變量。會話全局變量與特定會話相關(guān)聯(lián)并包含該會話獨有的值。已創(chuàng)建的會話全局變量可用于任何正在您定義該變量的數(shù)據(jù)庫上運行的活動 SQL 語句。系統(tǒng)目錄包含已創(chuàng)建的會話全局變量的定義以及與這些全局變量相關(guān)聯(lián)的特權(quán)。
例子:
創(chuàng)建全局變量:
CREATE VARIABLE myjob_current varchar (10) DEFAULT ('soft-engg');
獲取全局變量信息:
SELECT substr (varschema, 1, 10) as varschema,
substr (varname, 1, 10) AS varname,
varid, substr(owner,1,10) AS owner,
ownertype, create_time,
substr(typeschema,1,10) AS typeschema,
substr(typename,1,10) AS typename, length
FROM syscat.variables
WHERE varname = 'MYJOB_CURRENT';
給用戶praveen 和 sanjay 讀和寫權(quán)限,剝奪用戶sanjay寫權(quán)限:
GRANT READ, WRITE ON VARIABLE myjob_current TO USER praveen, USER sanjay;
REVOKE WRITE ON VARIABLE myjob_current FROM USER sanjay;
獲取用戶 praveen 和 sanjay 的全局變量權(quán)限信息:
SELECT substr (varschema, 1, 10) AS schema,
substr (varname, 1, 10) AS name,
substr(grantor,1,10) AS grantor, grantortype AS Rtype,
substr(grantee,1,10) AS grantee, granteetype AS Etype,
readauth, writeauth
FROM syscat.variableauth
WHERE varname ='MYJOB_CURRENT'; ]
在觸發(fā)器中使用全局變量,本例是設(shè)計一個disable觸發(fā)器示例:
CREATE VARIABLE disable_trigger char (1) DEFAULT ('N');
CREATE TRIGGER validate_t BEFORE INSERT ON EMPLOYEE
REFERENCING NEW AS n FOR EACH ROW
WHEN (disable_trigger = 'N' AND n.empno > '10000')
SIGNAL SQLSTATE '38000'
SET message_text = 'EMPLOYEE NUMBER TOO BIG and INVALID';
SET disable_trigger = 'Y'; 使觸發(fā)器失效
簡化用戶權(quán)限檢索:
CREATE VARIABLE schema1.gv_workdept CHAR
DEFAULT ((SELECT workdept FROM employee
WHERE firstnme = SESSION_USER));
CREATE VIEW schema1.emp_filtered AS
SELECT * FROM employee
WHERE workdept = schema1.gv_workdept;
在存儲過程,嵌入C,java程序中都可使用全局變量。
新的函數(shù)
新的函數(shù)簡化了應(yīng)用程序移植,版本 9.5 包含一些與其他數(shù)據(jù)庫供應(yīng)商使用的標量函數(shù)同名的新標量函數(shù)。當您將現(xiàn)有應(yīng)用程序移植到版本 9.5 中時,您可以繼續(xù)使用其他供應(yīng)商使用的函數(shù)名稱,而無需更改代碼。
提供了以下新的標量函數(shù):
• NVL(現(xiàn)有的 COALESCE 和 VALUE 函數(shù)的同義詞)
• LEAST 或 MIN(互為同義詞)
• GREATEST 或 MAX(互為同義詞)
• DECODE(類似于現(xiàn)有的 CASE 表達式)
