達夢6.0試用之PLSQL篇
前幾天ITPUB的熊建國主編和我聯絡,希望我能參加國產資料庫達夢的適用活動,並寫幾篇使用感受。本來最近手工的事情比較多,本打算推辭的,不過熊主編再三邀請,而且強調並非是槍手文,只要寫出真實使用感受即可。既然如此,我就本著支援國產資料庫的原則,寫幾篇試用感受。
由於本人唯一熟悉的資料庫就是Oracle,因此所有的對比都是與Oracle資料庫進行對比,在這個過程中,將盡可能避免將對Oracle資料庫的喜愛之情帶進來,爭取站在一個比較公正的位置上來進行評價。
這一篇簡單介紹一下達夢資料庫PL/SQL相關的內容。
達夢資料庫對於PL/SQL的支援也是出人意料的,基本上所有的關鍵性語法都與Oracle的PL/SQL沒有本質的區別。
SQL>BEGIN
2 INSERT INTO T VALUES (3, 'PL/SQL', SYSDATE);
3 END;
4 /
BEGIN
INSERT INTO T VALUES (3, 'PL/SQL', SYSDATE);
END;
1 rows affected
time used: 68.921(ms) clock tick:115154870.
SQL>BEGIN
2 EXECUTE IMMEDIATE 'TRUNCATE TABLE T';
3 END;
4 /
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE T';
END;
0 rows affected
time used: 31.029(ms) clock tick:51357350.
SQL>SELECT * FROM T;
SELECT * FROM T;
id name create_date
0 rows got
time used: 0.278(ms) clock tick:449080.
可以看到,不僅支援PL/SQL中包含的DML語句,而且連DDL語句都是支援的。
SQL>DECLARE
2 V_FLAG BOOLEAN;
3 BEGIN
4 FOR I IN 2 .. 100 LOOP
5 V_FLAG := TRUE;
6 FOR J IN 2 .. TRUNC(POWER(I, 0.5)) LOOP
7 IF MOD(I,J) = 0 THEN
8 V_FLAG := FALSE;
9 EXIT;
10 END IF;
11 END LOOP;
12
13 IF V_FLAG = TRUE THEN
14 --DBMS_OUTPUT.PUT_LINE(I);
15 NULL;
16 END IF;
17 END LOOP;
18 END;
19 /
DECLARE
V_FLAG BOOLEAN;
BEGIN
FOR I IN 2 .. 100 LOOP
V_FLAG := TRUE;
FOR J IN 2 .. TRUNC(POWER(I, 0.5)) LOOP
IF MOD(I,J) = 0 THEN
V_FLAG := FALSE;
EXIT;
END IF;
END LOOP;
IF V_FLAG = TRUE THEN
--DBMS_OUTPUT.PUT_LINE(I);
NULL;
END IF;
END LOOP;
END;
0 rows affected
time used: 108.993(ms) clock tick:181319230.
這時Oracle中計算100以內質數的一個PL/SQL過程,可以看到,除了呼叫DBMS_OUTPUT包之外,其他部分不用進行任何的修改就可以順利執行,在達夢的PL/SQL語句中,提供了PRINT語句來代替DBMS_OUTPUT包:
SQL>DECLARE
2 V_FLAG BOOLEAN;
3 BEGIN
4 FOR I IN 2 .. 100 LOOP
5 V_FLAG := TRUE;
6 FOR J IN 2 .. TRUNC(POWER(I, 0.5)) LOOP
7 IF MOD(I,J) = 0 THEN
8 V_FLAG := FALSE;
9 EXIT;
10 END IF;
11 END LOOP;
12
13 IF V_FLAG = TRUE THEN
14 PRINT(I);
15 END IF;
16 END LOOP;
17 END;
18 /
DECLARE
V_FLAG BOOLEAN;
BEGIN
FOR I IN 2 .. 100 LOOP
V_FLAG := TRUE;
FOR J IN 2 .. TRUNC(POWER(I, 0.5)) LOOP
IF MOD(I,J) = 0 THEN
V_FLAG := FALSE;
EXIT;
END IF;
END LOOP;
IF V_FLAG = TRUE THEN
PRINT(I);
END IF;
END LOOP;
END;
2
3
5
7
11
13
17
19
23
29
31
37
41
43
47
53
59
61
67
71
73
79
83
89
97
0 rows affected
time used: 29.325(ms) clock tick:48929860.
除了匿名塊外,達夢還支援PROCEDURE、FUNCTION和TRIGGER:
SQL>CREATE OR REPLACE PROCEDURE P_TEST AS
2 BEGIN
3 INSERT INTO T VALUES (1, 'TEST', SYSDATE);
4 COMMIT;
5 END;
6 /
CREATE OR REPLACE PROCEDURE P_TEST AS
BEGIN
INSERT INTO T VALUES (1, 'TEST', SYSDATE);
COMMIT;
END;
time used: 41.239(ms) clock tick:68574010.
SQL>SELECT * FROM T;
SELECT * FROM T;
id name create_date
0 rows got
time used: 0.319(ms) clock tick:520320.
SQL>BEGIN
2 P_TEST;
3 END;
4 /
BEGIN
P_TEST;
END;
1 rows affected
time used: 11.769(ms) clock tick:19487570.
SQL>SELECT * FROM T;
SELECT * FROM T;
id name create_date
1 1 TEST 2010-04-07
1 rows got
time used: 0.295(ms) clock tick:477140.
看一個函式的例子:
SQL>CREATE OR REPLACE FUNCTION F_TAX
2 (P_SALARY IN NUMBER, P_START IN NUMBER DEFAULT 2000)
3 RETURN NUMBER AS
4 V_SALARY NUMBER := P_SALARY - P_START;
5 BEGIN
6 IF V_SALARY <= 0 THEN
7 RETURN 0;
8 ELSIF V_SALARY <= 500 THEN
9 RETURN V_SALARY * 0.05;
10 ELSIF V_SALARY <= 2000 THEN
11 RETURN V_SALARY * 0.1 - 25;
12 ELSIF V_SALARY <= 5000 THEN
13 RETURN V_SALARY * 0.15 - 125;
14 ELSIF V_SALARY <= 20000 THEN
15 RETURN V_SALARY * 0.2 - 375;
16 ELSIF V_SALARY <= 40000 THEN
17 RETURN V_SALARY * 0.25 - 1375;
18 ELSIF V_SALARY <= 60000 THEN
19 RETURN V_SALARY * 0.3 - 3375;
20 ELSIF V_SALARY <= 80000 THEN
21 RETURN V_SALARY * 0.35 - 6375;
22 ELSIF V_SALARY <= 100000 THEN
23 RETURN V_SALARY * 0.4 - 10375;
24 ELSE
25 RETURN V_SALARY * 0.45 - 15375;
26 END IF;
27 END;
28 /
CREATE OR REPLACE FUNCTION F_TAX
(P_SALARY IN NUMBER, P_START IN NUMBER DEFAULT 2000)
RETURN NUMBER AS
V_SALARY NUMBER := P_SALARY - P_START;
BEGIN
IF V_SALARY <= 0 THEN
RETURN 0;
ELSIF V_SALARY <= 500 THEN
RETURN V_SALARY * 0.05;
ELSIF V_SALARY <= 2000 THEN
RETURN V_SALARY * 0.1 - 25;
ELSIF V_SALARY <= 5000 THEN
RETURN V_SALARY * 0.15 - 125;
ELSIF V_SALARY <= 20000 THEN
RETURN V_SALARY * 0.2 - 375;
ELSIF V_SALARY <= 40000 THEN
RETURN V_SALARY * 0.25 - 1375;
ELSIF V_SALARY <= 60000 THEN
RETURN V_SALARY * 0.3 - 3375;
ELSIF V_SALARY <= 80000 THEN
RETURN V_SALARY * 0.35 - 6375;
ELSIF V_SALARY <= 100000 THEN
RETURN V_SALARY * 0.4 - 10375;
ELSE
RETURN V_SALARY * 0.45 - 15375;
END IF;
END;
time used: 4.685(ms) clock tick:5683670.
SQL>SELECT F_TAX(10000) FROM T;
SELECT F_TAX(10000) FROM T;
1 1225
1 rows got
time used: 30.050(ms) clock tick:50174960.
這時以前寫的一個計算個人所得稅的函式,同樣沒有做任何的修改,放在達夢資料庫上就可以直接執行。
下面是一個PACKAGE的例子:
SQL>CREATE OR REPLACE PACKAGE PA_TEST AS
2 PROCEDURE P_TEST(P_IN NUMBER);
3 PROCEDURE P_TEST(P_IN VARCHAR);
4 END;
5 /
CREATE OR REPLACE PACKAGE PA_TEST AS
PROCEDURE P_TEST(P_IN NUMBER);
PROCEDURE P_TEST(P_IN VARCHAR);
END;
time used: 80.545(ms) clock tick:134160000.
SQL>CREATE OR REPLACE PACKAGE BODY PA_TEST AS
2 PROCEDURE P_TEST(P_IN NUMBER) AS
3 BEGIN
4 PRINT('NUMBER');
5 END;
6
7 PROCEDURE P_TEST(P_IN VARCHAR) AS
8 BEGIN
9 PRINT('VARCHAR');
10 END;
11 END;
12 /
CREATE OR REPLACE PACKAGE BODY PA_TEST AS
PROCEDURE P_TEST(P_IN NUMBER) AS
BEGIN
PRINT('NUMBER');
END;
PROCEDURE P_TEST(P_IN VARCHAR) AS
BEGIN
PRINT('VARCHAR');
END;
END;
time used: 20.445(ms) clock tick:33862040.
SQL>BEGIN
2 PA_TEST.P_TEST(1);
3 END;
4 /
BEGIN
PA_TEST.P_TEST(1);
END;
NUMBER
0 rows affected
time used: 0.552(ms) clock tick:913600.
SQL>BEGIN
2 PA_TEST.P_TEST('1');
3 END;
4 /
BEGIN
PA_TEST.P_TEST('1');
END;
VARCHAR
0 rows affected
time used: 0.441(ms) clock tick:725060.
這個例子顯示了包中過程的過載特性。
看一個觸發器的例子:
SQL>CREATE OR REPLACE TRIGGER T_TRI
2 BEFORE DELETE ON T
3 FOR EACH ROW
4 BEGIN
5 INSERT INTO T_BAK VALUES (:OLD.ID);
6 END;
7 /
CREATE OR REPLACE TRIGGER T_TRI
BEFORE DELETE ON T
FOR EACH ROW
BEGIN
INSERT INTO T_BAK VALUES (:OLD.ID);
END;
time used: 13.493(ms) clock tick:22369710.
SQL>INSERT INTO T VALUES (2, 'ABC', SYSDATE);
INSERT INTO T VALUES (2, 'ABC', SYSDATE)
1 rows affected
time used: 0.376(ms) clock tick:614380.
SQL>INSERT INTO T VALUES (3, 'TTT', NULL);
INSERT INTO T VALUES (3, 'TTT', NULL)
1 rows affected
time used: 0.497(ms) clock tick:818040.
SQL>DELETE T;
DELETE T;
3 rows affected
time used: 0.730(ms) clock tick:1203390.
SQL>SELECT * FROM T_BAK;
SELECT * FROM T_BAK;
ID
1 1
2 2
3 3
3 rows got
time used: 0.370(ms) clock tick:602660.
達夢支援這種最普通的DML的觸發器,還支援INSTEAD OF觸發器、但是並不支援基於資料庫事件的觸發器和基於資料庫錯誤的觸發器。
達夢資料庫的FETCH語句和PL/SQL的相比更加靈活一些,提供了隨機讀取的功能:
SQL>INSERT INTO T VALUES (1, 'A', NULL);
INSERT INTO T VALUES (1, 'A', NULL)
1 rows affected
time used: 0.461(ms) clock tick:757930.
SQL>INSERT INTO T VALUES (2, 'B', SYSDATE);
INSERT INTO T VALUES (2, 'B', SYSDATE)
1 rows affected
time used: 0.430(ms) clock tick:701910.
SQL>INSERT INTO T VALUES (3, 'ABC', '');
INSERT INTO T VALUES (3, 'ABC', '')
1 rows affected
time used: 0.333(ms) clock tick:540330.
SQL>DECLARE
2 V_NUM NUMBER;
3 C_CUR CURSOR;
4 BEGIN
5 OPEN C_CUR FOR 'SELECT ID FROM T';
6 FETCH LAST C_CUR INTO V_NUM;
7 PRINT(V_NUM);
8 FETCH PRIOR C_CUR INTO V_NUM;
9 PRINT(V_NUM);
10 FETCH ABSOLUTE 0 C_CUR INTO V_NUM;
11 PRINT(V_NUM);
12 CLOSE C_CUR;
13 END;
14 /
DECLARE
V_NUM NUMBER;
C_CUR CURSOR;
BEGIN
OPEN C_CUR FOR 'SELECT ID FROM T';
FETCH LAST C_CUR INTO V_NUM;
PRINT(V_NUM);
FETCH PRIOR C_CUR INTO V_NUM;
PRINT(V_NUM);
FETCH ABSOLUTE 0 C_CUR INTO V_NUM;
PRINT(V_NUM);
CLOSE C_CUR;
END;
3
2
1
0 rows affected
time used: 0.726(ms) clock tick:1199160.
其中FETCH語句指定ABSOLUTE的數值時,是從0開始的,這顯然是C語言的習慣。
達夢資料庫還有一個優點,無論是匿名塊還是過程,在SELECT的時候可以不指定FETCH的變數,這時會將查詢結果直接輸出到螢幕上:
SQL>BEGIN
2 SELECT * FROM T;
3 END;
4 /
BEGIN
SELECT * FROM T;
END;
id name create_date
1 1 A NULL
2 2 B 2010-04-07
3 3 ABC NULL
3 rows got
time used: 0.496(ms) clock tick:816250.
不過達夢資料庫的PL/SQL也有不足之處,比如不支援TYPE,不支援索引表、巢狀表和陣列。
由於不支援巢狀表和索引表,顯然也是不支援批次操作的,無論是批次插入和批次讀取都是達夢目前所不支援的。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4227/viewspace-668414/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 達夢6.0試用之SQL篇SQL
- 達夢6.0試用之架構篇架構
- 達夢6.0試用之資料字典
- 達夢6.0試用之測試環境搭建
- 達夢6.0試用之資料庫物件資料庫物件
- 達夢6.0試用之資料型別資料型別
- 達夢6.0試用之併發和鎖機制
- 達夢6.0 for Windows安裝Windows
- 達夢資料庫之初步測試資料庫
- 【開發篇plsql】plsql遊標SQL
- 達夢資料庫必知必會-DCA篇資料庫
- 達夢DIsqlSQL
- 【開發篇plsql】plsql物件型別SQL物件型別
- 【開發篇plsql】plsql事務處理SQL
- 達夢安裝
- 【達夢】Docker安裝達夢資料庫 dm8Docker資料庫
- git使用之idea篇GitIdea
- 達夢遷移工具之MySQL資料庫遷移到達夢MySql資料庫
- 【開發篇plsql】plsql資料型別(二) recordSQL資料型別
- Asp之IIS 6.0搭建篇
- Google BERT中文應用之《紅樓夢》對話人物提取Go
- DBeave如何連線達夢資料庫,設定達夢驅動,真酷資料庫
- 達夢DMDSC叢集搭建
- 達夢資料庫DM8共享叢集測試記錄資料庫
- 【開發篇plsql】plsql資料型別(一) 集合型別SQL資料型別
- 達夢資料庫DM8主備叢集測試記錄資料庫
- 達夢資料庫開發資料庫
- 初識達夢資料庫資料庫
- 達夢SQL優化方法statSQL優化
- 達夢資料庫學習資料庫
- 達夢資料庫安裝資料庫
- Android ADB使用之詳細篇Android
- 達夢資料庫基礎知識(三)達夢資料庫記憶體結構資料庫記憶體
- 達夢dmfldr資料快速載入
- 達夢dmfldr載入大欄位
- Redhat 7 下安裝達夢7Redhat
- 達夢列儲存表(HUGE Table)
- 效能優化之達夢AWR使用優化