設計資料庫應用時,資料變更邏輯的放置位置取決於四大因素:
| 優勢 | 風險/考量 |
|---|---|
| 應用程式與資料解耦,修改一次即影響所有消費者 | 規則普遍套用,可能不符特定應用需求 |
| 集中管理業務規則 (RI、Check、Trigger、SP、UDF) | 伺服器端運算資源爭用,需評估 Client/Server 分工 |
| 效能:就近處理資料,減少網路往返 | 廠商鎖定風險,移植困難 |
最佳實務: 資料驗證 (輸入階段) 放應用端;參考完整性、跨表業務規則、複雜計算放資料庫端 (SP/UDF/Trigger)。
SELECT 僅宣告「要什麼」,不指定「怎麼取」。REFRESH IMMEDIATE (基表異動即時同步) / REFRESH DEFERRED (手動 REFRESH TABLE)。CONNECT TO SAMPLE;
ALTER TABLE EMPLOYEE ADD UNIQUE (EMPNO);
ALTER TABLE DEPARTMENT ADD UNIQUE (DEPTNO);
CREATE TABLE EMP AS (
SELECT E.EMPNO, E.FIRSTNME, E.LASTNAME, E.PHONENO,
D.DEPTNO, SUBSTR(D.DEPTNAME,1,12) AS DEPARTMENT, D.MGRNO
FROM EMPLOYEE E, DEPARTMENT D
WHERE E.WORKDEPT = D.DEPTNO
) DATA INITIALLY DEFERRED REFRESH IMMEDIATE;
SET INTEGRITY FOR EMP IMMEDIATE CHECKED NOT INCREMENTAL;
前提: 參與查詢的每個基表至少有一個唯一鍵出現在 SELECT 清單中。
SYSIBM Schema:彙總 (AVG)、運算子 (+)、型別轉換 (DECIMAL)、字串 (SUBSTR) 等。SYSCAT.FUNCTIONS,CREATE FUNCTION 定義。db2udf 進程,共享記憶體通訊,安全穩定,效能稍低。-- 空值轉預設
SELECT TITLE, COALESCE(PRICE, 0.00) FROM TITLES;
-- 字串長度
SELECT COMPANYNAME, LENGTH(COMPANYNAME) FROM CUSTOMERS;
-- 取右 5 字元
SELECT RIGHT(AU_FNAME, 5) FROM AUTHORS;
-- 宿主變數接收彙總值
SELECT AVG(PRSTAFF) INTO :AVERAGE FROM PROJECT WHERE DEPTNO = 'D11';
WITH PROD_QUANTITY AS (
SELECT PRODUCT_ID, SUM(QUANTITY) AS QUANTITY
FROM CUSTOMER_ORDER_ITEM GROUP BY PRODUCT_ID
),
TOTALS AS (
SELECT -1 AS PRODUCT_ID, SUM(QUANTITY) AS TOTAL
FROM PROD_QUANTITY
)
SELECT PRODUCT_ID, QUANTITY FROM PROD_QUANTITY
UNION
SELECT PRODUCT_ID, TOTAL FROM TOTALS
ORDER BY 1 DESC;
SELECT INTO 僅支援單列。WHERE CURRENT OF cursor)。| 特徵 | 選項 | |
|---|---|---|
| Type | Read-only / Updatable / Ambiguous | |
| Direction | Forward-only / Scrollable | |
| Scope | Local / Global (Stored Procedure 用 WITH RETURN) |
| 介面 | 游標宣告/建立 | 額外功能 |
|---|---|---|
| Embedded SQL (C/C++/COBOL) | EXEC SQL DECLARE / OPEN / FETCH / CLOSE | 單向單列 |
| SQL PL | 類 C,支援 WITH RETURN 傳回結果集 | 結果集外傳 |
| CLI/ODBC | SQLExecDirect 自動建立 | 捲動、批次擷取、多列前移 |
| JDBC | 建立 ResultSet 時自動建立 | 同 CLI,支援可更新 ResultSet |
| SQLJ | Iterator (迭代器) 概念 | 強型別、命名/位置迭代器 |
EXEC SQL DECLARE C0 CURSOR FOR SELECT DEPTNUMB, DEPTNAME FROM ORG;
EXEC SQL OPEN C0;
EXEC SQL FETCH C0 INTO :DEPTNUMB, :DEPTNAME;
while (SQLCA.SQLCODE != 100) {
printf("%8d %-14s\n", DEPTNUMB, DEPTNAME);
EXEC SQL FETCH C0 INTO :DEPTNUMB, :DEPTNAME;
}
EXEC SQL CLOSE C0;