SQL 作為關聯式資料庫標準語言,已被 Oracle、Sybase、Informix 等主流 DBMS 採用。Delphi 透過 TQuery 元件提供完整 SQL 程式設計支援,包含靜態/動態 SQL、參數綁定、異構查詢、活動/唯讀結果集控制等企業級特性。
| 資料源類型 | 支援 SQL 範圍 | 備註 |
|---|---|---|
| Paradox / dBASE (本地) | Local SQL (ANSI-92 子集) | SELECT、INSERT、UPDATE、DELETE |
| InterBase (本地) | 完整 InterBase SQL | 含預存程序、觸發器 |
| 遠端 DBMS (Oracle, Sybase, MS SQL…) | 該 DBMS 完整 SQL | 需安裝對應 SQL Link |
| 異構查詢 | 跨多資料庫聯查 | 如 Oracle 表 JOIN Sybase 表 |
DatabaseName (BDE 別名或 TDatabase 別名)SQL 屬性 (字串清單)Query.Close; Query.SQL.Clear; Query.SQL.Add('...');Open:僅 SELECT,回傳結果集ExecSQL:INSERT/UPDATE/DELETE/DDL,無結果集Prepare → 參數賦值 → Open/ExecSQL{ 靜態 SQL - 設計期固定 }
Query1.SQL.Text := 'SELECT * FROM Customer WHERE CustNo = 1234';
{ 動態 SQL - 參數化 }
Query1.SQL.Text := 'SELECT * FROM Customer WHERE CustNo = :Num';
Query1.ParamByName('Num').AsInteger := Edit1.Text.ToInteger;
Query1.Open;
| 方式 | 適用場景 | 範例 |
|---|---|---|
Params[索引] | 參數順序固定、無名稱依賴 | Query.Params[0].AsString := 'A' |
ParamByName('名稱') | 參數名稱語意化、順序可變 | Query.ParamByName('CustNo').AsInteger := 100 |
DataSource 主從聯動 | 主表游標移動自動帶入參數 | Master TTable → DataSource → Detail TQuery |
Prepare:送交 DBMS 剖析、優化、編譯執行計畫,重複執行同一 SQL 必呼叫Unprepare:釋放 DBMS 資源,良好習慣於查詢結束後呼叫Prepared 可檢查是否已準備| 條件 | RequestLive | CanModify | 結果集類型 |
|---|---|---|---|
| 預設 | False | False | 唯讀 |
| 滿足限制 | True | True | 活動 (可編輯回寫) |
| 不滿足限制 | True | False | 唯讀 (本地) / 錯誤 (遠端) |
活動結果集限制:單表、無 ORDER BY、無聚合、無計算欄位、WHERE 僅支援欄位與常數比較 (LIKE, >, <, = 等)。
元件:Memo1 (SQL 輸入)、DBGrid1 (結果)、Query1、DataSource1、三按鈕
procedure TForm1.BtnExecuteClick(Sender: TObject);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.SQL.Text := Memo1.Text;
try
Query1.Open; // SELECT
except
Query1.ExecSQL; // 非 SELECT
end;
end;
procedure TForm1.BtnClearClick(Sender: TObject);
begin
Query1.Close;
Query1.SQL.Clear;
Query1.ExecSQL; // 清空 Grid
end;
支援:別名選擇 → 表選擇 → 欄位選擇 → 運算子 (=, >, LIKE… ) → 值輸入 → 動態建構 WHERE → 執行顯示。核心邏輯見 BitBtn2Click 以 case 產生 strWhere,再組裝 SELECT * FROM "Table" t WHERE t.欄位 運算子 值。
{ 關鍵片段:動態建構 WHERE 子句 }
case etSQLOps(ComboBox1.ItemIndex) of
soEqual: strWhere := strField + ' = ' + strQuote + strValue + strQuote;
soLike: strWhere := strField + ' LIKE ' + strQuote + strValue + '%' + strQuote;
soBetween: strWhere := strField + ' BETWEEN ' + strQuote + strVal1 + strQuote +
' AND ' + strQuote + strVal2 + strQuote;
soIn: strWhere := strField + ' IN (' + strQuote + strValues + strQuote + ')';
soIsNull: strWhere := strField + ' IS NULL';
// ... 其他運算子
end;
strQuery := 'SELECT * FROM "' + strTable + '"';
if strWhere <> '' then strQuery := strQuery + ' WHERE ' + strWhere;
Query1.Close; Query1.SQL.Clear; Query1.SQL.Add(strQuery); Query1.Open;
ParamByName 提升可讀性與維護性Prepare / UnprepareUniDirectional = True 加速CanModify,不符限制改用第二 TQuery 執行 UPDATE