嵌入式 SQL 將 SQL 陳述式嵌入高階語言(C、Cobol、Fortran 等),程式中共存兩種模型:
三大溝通機制解決模型不匹配:
SQLCA (SQL Communication Area) 是預先定義的資料結構,每次 SQL 執行後,DBMS 將狀態碼、錯誤訊息、列計數等回填至此。應用程式檢查 SQLCODE(或 SQLSTATE)決定後續流程。
EXEC SQL INCLUDE SQLCA; -- 定義 SQLCA
EXEC SQL DELETE FROM emp WHERE dept = :dno;
IF SQLCODE = 0 THEN -- 成功
...
ELSE IF SQLCODE = 100 THEN -- 無符合列
...
ELSE -- 其他錯誤
...
END IF;
典型回饋:違反約束拒絕、無列刪除、成功刪除並回傳筆數、無條件刪除警告、執行錯誤。
主語言變數在 SQL 中使用,前綴冒號 : 識別。
| 類型 | 方向 | 用途 |
|---|---|---|
| 輸入主變數 | 主語言 → SQL | 提供參數值(WHERE col = :var)。 |
| 輸出主變數 | SQL → 主語言 | 接收查詢結果(INTO :var1, :var2)。 |
| 輸入/輸出 | 雙向 | 同一變數先輸入後輸出。 |
整數變數,緊跟主變數後(:var :ind),用途:
ind = -1 表示傳遞 NULL 值。ind = -1 表示接收到 NULL;ind > 0 表示值被截斷(長度為 ind)。
EXEC SQL BEGIN DECLARE SECTION;
char emp_name[64];
long emp_id;
short emp_id_ind; -- 指示變數
EXEC SQL END DECLARE SECTION;
解決「集合導向 SQL 產生多列」與「記錄導向主語言一次處理一列」的不匹配。
#include
#include
EXEC SQL BEGIN DECLARE SECTION;
char dept_name[64];
char emp_no[64], emp_name[64], emp_sex[64];
int emp_age, new_age;
long SQLCODE;
EXEC SQL END DECLARE SECTION;
EXEC SQL INCLUDE sqlca;
int main() {
int count = 0; char yn;
printf("Dept (CS/MA/IS): "); scanf("%s", dept_name);
EXEC SQL CONNECT TO 'HP-08D6CXF128B\SQL2000' USER 'sa';
EXEC SQL DECLARE SX CURSOR FOR
SELECT emp_no, emp_name, emp_sex, emp_age
FROM employee
WHERE dept = :dept_name;
EXEC SQL OPEN SX;
for (;;) {
EXEC SQL FETCH SX INTO :emp_no, :emp_name, :emp_sex, :emp_age;
if (sqlca.sqlcode != 0) break; -- SQLCODE=100 表示無更多列
if (count++ == 0) printf("%-10s %-20s %-10s %-10s\n", "No", "Name", "Sex", "Age");
printf("%-10s %-20s %-10s %-10d\n", emp_no, emp_name, emp_sex, emp_age);
printf("UPDATE AGE (y/n)? ");
do { scanf(" %c", &yn); } while (yn!='Y'&&yn!='y'&&yn!='N'&&yn!='n');
if (yn=='Y'||yn=='y') {
printf("NEW AGE: "); scanf("%d", &new_age);
EXEC SQL UPDATE employee SET emp_age = :new_age WHERE CURRENT OF SX;
}
}
EXEC SQL CLOSE SX;
EXEC SQL COMMIT WORK;
EXEC SQL DISCONNECT;
return 0;
}
DECLARE → OPEN → FETCH → (UPDATE/DELETE WHERE CURRENT OF) → CLOSE 生命週期,逐列處理結果集。WHERE CURRENT OF cursor 實現精確定位更新,避免 WHERE 條件不唯一風險。EXEC SQL 區塊轉換為呼叫資料庫客戶端庫的函式呼叫。