首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> Delphi

Delphi 呼叫預存程序完整實作:ADOStoredProc 參數建立、結果集處理與 DataGrid 綁定

     編輯:Delphi

前言

在 Delphi 中使用 TADOStoredProc 呼叫資料庫預存程序,關鍵在於參數正確建立與綁定、區分有無結果集、異常處理。本文提供從資料模組設計到 UI 綁定的完整實作範例。

資料模組設計 (DataModule)

unit DataMConn;

interface

uses
  SysUtils, Classes, DB, ADODB;

type
  TDataModule1 = class(TDataModule)
    ADOConn: TADOConnection;
    ADOSP: TADOStoredProc;
    DSP: TDataSource;
    procedure DataModuleCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  DataModule1: TDataModule1;

implementation

{$R *.dfm}

procedure TDataModule1.DataModuleCreate(Sender: TObject);
begin
  ADOConn.ConnectionString := 
    'Provider=SQLOLEDB.1;Server=.;Database=TestDB;Integrated Security=SSPI;';
  ADOConn.LoginPrompt := False;
  ADOConn.Connected := True;
  
  DSP.DataSet := ADOSP; // 綁定 DataSource
end;

end.

呼叫預存程序核心程式碼

procedure TForm1.CallStoredProc;
var
  SP: TADOStoredProc;
begin
  SP := DataModule1.ADOSP;
  
  // 1. 指定預存程序名稱
  SP.ProcedureName := 'GetAbove'; // 例如:CREATE PROC GetAbove @tableName varchar(20), @strDate varchar(20)
  
  // 2. 清除舊參數 (重要:避免重複呼叫時參數殘留)
  SP.Parameters.Clear;
  
  // 3. 建立輸入參數
  // CreateParameter(Name, DataType, Direction, Size, Value)
  SP.Parameters.CreateParameter('@tableName', ftString, pdInput, 20, 'TableA');
  SP.Parameters.CreateParameter('@strDate', ftString, pdInput, 20, '2024-01-15');
  
  // 4. 若有輸出參數
  // SP.Parameters.CreateParameter('@RowCount', ftInteger, pdOutput, 0, 0);
  
  // 5. 參數賦值 (也可在第 3 步直接給 Value)
  SP.Parameters.ParamByName('@tableName').Value := 'TableA';
  SP.Parameters.ParamByName('@strDate').Value := '2024-01-15';
  
  try
    // 6. 執行:有結果集用 Open,無結果集用 ExecProc
    SP.Open; 
    
    // 7. 讀取輸出參數 (若有)
    // var RowCount: Integer := SP.Parameters.ParamByName('@RowCount').Value;
    
    // 8. 綁定到 DataGrid
    DBGrid1.DataSource := DataModule1.DSP;
    
  except
    on E: Exception do
    begin
      ShowMessage('預存程序執行錯誤: ' + E.Message);
      SP.Close; // 確保關閉
    end;
  end;
end;

參數方向與資料類型對照

方向常數用途對應 SQL
pdInput輸入參數@Param IN
pdOutput輸出參數@Param OUT
pdInputOutput輸入輸出參數@Param IN OUT
pdReturnValue返回值RETURN @Val
Delphi ftTypeSQL Server 類型備註
ftStringvarchar/nvarcharSize 指定長度
ftWideStringnvarcharUnicode 字串
ftIntegerint
ftLargeintbigint
ftFloatfloat/real
ftBCDdecimal/numeric精確數值
ftDateTimedatetime/datetime2
ftBooleanbit
ftBlobvarbinary(max)/image二進位資料

進階:動態建立參數 (適用未知參數結構)

procedure PrepareSPParameters(SP: TADOStoredProc; const ParamValues: array of Variant);
var
  I: Integer;
  Param: TParameter;
begin
  SP.Parameters.Refresh; // 從資料庫自動獲取參數元資料 (需連線)
  
  // 或手動根據陣列建立
  SP.Parameters.Clear;
  for I := 0 to High(ParamValues) do
  begin
    Param := SP.Parameters.CreateParameter(
      '@Param' + IntToStr(I + 1), 
      ftVariant, pdInput, 0, ParamValues[I]);
    // ftVariant 由 ADO 自動推斷類型
  end;
end;

多結果集處理 (SQL Server)

// 預存程序返回多個 SELECT
SP.Open; // 取得第一個結果集
while not SP.Recordset.EOF do
begin
  // 處理第一個結果集
  SP.Recordset.MoveNext;
end;

// 移至下一個結果集
if SP.Recordset.NextRecordset(Pointer(0)) then
begin
  // 處理第二個結果集
  // 可建立另一個 TADODataSet 綁定
  // ADODataSet2.Recordset := SP.Recordset;
end;

常見錯誤與排查

錯誤現象可能原因解決方案
"Parameter '@xxx' not found"參數名稱拼寫錯誤、大小寫不符 (SQL Server 不區分大小寫但 ADO 可能區分)使用 ParamByName、檢查 ProcedureName 正確、執行 Parameters.Refresh
"Data type mismatch"Delphi ftType 與 SQL 類型不符對照類型表、數值型別注意 ftBCD vs ftFloat
ExecProc 無反應/掛住預存程序內有長時間運算、死結設定 SP.CommandTimeout、優化 SP、非同步執行
結果集為空但應有資料用 ExecProc 而非 Open有 SELECT 回傳必須用 Open
輸出參數值為 Null未在 SP 中正確 SET、方向錯誤檢查 SP 定義 OUTPUT、ADO 參數方向 pdOutput

最佳實務總結

  1. 集中管理:預存程序呼叫邏輯封裝在資料模組或專用 Service 類別
  2. 參數化:絕不拼接 SQL 字串,防注入、利用快取計畫
  3. 資源釋放:try...finally SP.Close; end 確保游標關閉
  4. 錯誤包裝:捕獲 EADOError 轉換為業務例外,記錄 SQL 與參數值便於除錯
  5. 效能:重複呼叫同一 SP 時,重用 TADOStoredProc 實例,僅更新參數值

結語

TADOStoredProc 提供了結構化、型別安全的預存程序呼叫介面。掌握 Parameters.Clear → CreateParameter → ParamByName → Open/ExecProc 這套標準流程,配合資料模組集中連線管理,即能建構穩健、可維護的資料存取層。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved