SQLJ (Embedded SQL in Java) 允許在 Java 程式碼中直接撰寫 SQL,經預編譯器轉換為標準 JDBC 程式碼。本文完整示範從原始碼建立、預編譯、連線資料庫到游標操作的全流程。
#sql { SQL語句 } 格式嵌入 SQLsqlj 檔案名.sqlj 生成 .java 與 _SJProfileKeys.ser 等產出物import java.sql.*;
import sqlj.runtime.*;
import sqlj.runtime.ref.*;
// 宣告迭代器 (對應 ResultSet)
#sql iterator App_Cursor1 (String empno, String firstnme);
#sql iterator App_Cursor2 (String firstnme);
class App {
static {
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] argv) {
try {
App_Cursor1 cursor1;
App_Cursor2 cursor2;
String str1 = null, str2 = null;
int count1;
Connection con = null;
String url = "jdbc:odbc:tese2";
DefaultContext ctx = DefaultContext.getDefaultContext();
// 取得或建立連線上下文
if (ctx == null) {
try {
if (argv.length == 0) {
String userid = "tdl";
String passwd = "user";
con = DriverManager.getConnection(url, userid, passwd);
} else if (argv.length == 2) {
con = DriverManager.getConnection(url);
} else {
System.out.println("Usage: java App [username passWord]");
System.exit(0);
}
con.setAutoCommit(false);
ctx = new DefaultContext(con);
} catch (SQLException e) {
System.out.println("Error: could not get a default context");
System.err.println(e);
System.exit(1);
}
DefaultContext.setDefaultContext(ctx);
}
// === 範例 1:查詢全表,使用具名迭代器 ===
#sql cursor1 = { SELECT empno, firstnme FROM db2admin.employee };
System.out.println("Received results:");
while (cursor1.next()) {
str1 = cursor1.empno();
str2 = cursor1.firstnme();
System.out.print(" empno= " + str1);
System.out.print(" firstname= " + str2);
System.out.print("");
}
cursor1.close();
// === 範例 2:參數化查詢,使用位置迭代器 + FETCH ===
#sql cursor2 = { SELECT firstnme FROM db2admin.employee WHERE empno = :str1 };
System.out.println("Received results:");
while (true) {
#sql { FETCH :cursor2 INTO :str2 };
if (cursor2.endFetch()) break;
System.out.print(" empno= " + str1);
System.out.print(" firstname= " + str2);
System.out.print("");
}
cursor2.close();
// 回滾測試
System.out.println("Rollback the update...");
#sql { ROLLBACK WORK };
System.out.println("Rollback done.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
| 類型 | 宣告語法 | 適用場景 |
|---|---|---|
| 具名迭代器 | #sql iterator Name (Type colName, ...); | 按欄位名存取,程式碼可讀性高 |
| 位置迭代器 | #sql iterator Name (Type, ...); | 配合 FETCH ... INTO 使用,適合動態欄位 |
:str1 — 輸入參數 (IN):str2 — 輸出參數 (OUT)DefaultContext:SQLJ 執行環境的核心,封裝 JDBC ConnectionsetDefaultContext():設定執行緒預設上下文,後續 #sql 直接使用直接在 #sql { COMMIT } / #sql { ROLLBACK } 中執行,無需呼叫 JDBC API。
sun.jdbc.odbc.JdbcOdbcDriver),需預先在系統配置 ODBC 資料源oracle.jdbc.OracleDriver、com.ibm.db2.jcc.DB2Driver)sqlj App.sqlj → 生成 App.java → 再以 javac 編譯SQLJ 讓 Java 開發者能以類似 PL/SQL 的直觀方式撰寫資料庫邏輯,配合強型別檢查與預編譯優化,是嵌入式 SQL 開發的利器。掌握迭代器、主機變數、上下文管理三大核心,即可輕鬆駕馭企業級資料存取開發。