PowerBuilder (PB) 作為經典的客戶端/服務器 (C/S) 開發工具,其嵌入式 SQL (ESQL) 語法融合了腳本語言靈活性與數據庫操作強大功能。本文系統整理 PB 中 SELECT、INSERT、UPDATE、DELETE、游標、BLOB、動態 SQL、事務控制等核心語句的語法規範、參數綁定、錯誤處理與最佳實踐,為 PB 開發者提供即查即用的參考手冊。
&。:emp_id。''張% 表示 '張%')。SQLCA),需先 CONNECT 後操作,最後 COMMIT 或 ROLLBACK。SELECT Employee.Emp_id, Employee.Emp_name, Employee.Emp_salary, Dept.Dept_name
FROM Employee, Dept
WHERE (Emp_name LIKE :ls_name_pattern) AND (Emp_sex = :ls_sex)
AND Employee.Dept_id = Dept.Dept_id
ORDER BY Employee.Emp_id;
DECIMAL ld_max_salary
SELECT MAX(Emp_salary) INTO :ld_max_salary FROM Employee;
INTEGER li_emp_nbr
STRING ls_emp_name
li_emp_nbr = Integer(sle_number.Text)
ls_emp_name = sle_name.Text
INSERT INTO Employee (Emp_nbr, Emp_name)
VALUES (:li_emp_nbr, :ls_emp_name)
USING Emp_tran; -- 指定事務對象,可省略用默認 SQLCA
UPDATE Employee
SET Emp_name = :sle_Name.Text
WHERE Emp_nbr = :li_emp_nbr;
DELETE FROM Employee
WHERE Emp_nbr < 100;
CONNECT:建立連接 (隱含 BEGIN TRANSACTION)。COMMIT:提交事務,DISCONNECT 前自動執行。ROLLBACK:回滾事務。DISCONNECT:斷開連接 (隱含 COMMIT)。游標生命週期:DECLARE → OPEN → FETCH → (循環 FETCH) → CLOSE。可在 FETCH 後對當前行執行 UPDATE ... WHERE CURRENT OF cursor / DELETE ... WHERE CURRENT OF cursor。
// 聲明游標及宿主變量
STRING ls_emp_name
DECLARE emp_cur CURSOR FOR
SELECT emp_name FROM EMPLOYEE WHERE emp_state = :sle_1.Text;
// 打開游標 (執行 SELECT)
OPEN emp_cur;
// 取第一行
FETCH emp_cur INTO :ls_emp_name;
// 錯誤檢查
IF SQLCA.SQLCode < 0 THEN
MessageBox("Database Error", SQLCA.SQLErrText)
RETURN
END IF
// 循環取數據
DO WHILE SQLCA.SQLCode = 0
ddlb_1.AddItem(ls_emp_name) // 加入下拉列表
FETCH emp_cur INTO :ls_emp_name
LOOP
// 關閉游標 (釋放資源)
CLOSE emp_cur;
BLOB 操作單次僅能處理一行,多行會報錯。需聲明 BLOB 類型變量作為中介。
BLOB lblb_emp_pic
SELECTBLOB Emp_pic INTO :lblb_emp_pic
FROM Employee
WHERE Emp_Id = '001'
USING Emp_tran;
IF Emp_tran.SQLCode = 0 THEN
pb_1.SetPicture(lblb_emp_pic) // Picture 控件顯示
END IF
INTEGER li_file_handle
BLOB lblb_emp_pic
// 以流模式讀取文件
li_file_handle = FileOpen("c:\emp_100.bmp", StreamMode!)
IF li_file_handle <> -1 THEN
FileRead(li_file_handle, lblb_emp_pic)
FileClose(li_file_handle)
UPDATEBLOB Employee
SET Emp_pic = :lblb_emp_pic
WHERE Emp_Id = '001';
IF SQLCA.SQLNRows > 0 THEN
COMMIT USING Emp_tran;
ELSE
ROLLBACK USING Emp_tran;
END IF
END IF
適用於表名、列名、WHERE 條件動態變化的場景。核心對象:事務對象 (SQLCA)、動態描述區 (SQLDA - 輸入/輸出參數描述)。
STRING ls_sql
ls_sql = "CREATE TABLE Employee (" + &
"emp_id CHAR(6) NOT NULL," + &
"emp_nbr INTEGER NOT NULL," + &
"dept_id INTEGER NOT NULL," + &
"emp_fname CHAR(10) NOT NULL," + &
"emp_lname CHAR(20) NOT NULL)"
EXECUTE IMMEDIATE :ls_sql;
// 等價於
EXECUTE IMMEDIATE "DROP TABLE Employee" USING My_trans;
INTEGER li_dept_id = 156
STRING ls_dept_name
SetNull(ls_dept_name)
CONNECT USING My_trans;
// 預編譯 (參數用 ? 佔位)
PREPARE SQLCA FROM "INSERT INTO Dept VALUES (?, ?)";
// 執行並綁定參數
EXECUTE SQLCA USING :li_dept_id, :ls_dept_name;
DECLARE dyn_cur DYNAMIC CURSOR FOR SQLCA;
PREPARE SQLCA FROM "SELECT * FROM Employee WHERE Dept_id = ? AND Salary > ?";
OPEN DYNAMIC dyn_cur USING :li_dept_id, :ld_min_salary;
FETCH dyn_cur INTO :ls_emp_id, :ls_emp_name, :ld_salary;
...
CLOSE dyn_cur;
IF SQLCA.SQLCode < 0 THEN
MessageBox("DB Error", "Code: " + String(SQLCA.SQLCode) + "~r~n" + SQLCA.SQLErrText)
ROLLBACK USING SQLCA; -- 或指定事務對象
RETURN
END IF
-- 針對 UPDATE/DELETE/INSERT 可檢查影響行數
IF SQLCA.SQLNRows = 0 THEN
-- 未找到匹配行,業務邏輯判斷
END IF
EXECUTE IMMEDIATE 批量 DML 或外部工具 (bcp/BULK INSERT)。PowerBuilder ESQL 以 冒號綁定變量、分號終止、事務對象管理、游標逐行處理、BLOB 專用語句、動態 SQL 多格式支援 為核心特徵。掌握 DECLARE/OPEN/FETCH/CLOSE 游標循環範式、SELECTBLOB/UPDATEBLOB 雙向流操作、PREPARE/EXECUTE 參數化動態執行三大進階模式,並將 SQLCA.SQLCode 檢查內化為肌肉記憶,即可駕馭 PB 數據庫開發的 95% 場景。記住:靜態優於動態、綁定優於拼接、簡潔優於花哨。