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

Delphi 編寫 SQL Server 2000 擴展存儲過程:字符串參數處理與結果集返回實戰

     編輯:Delphi

前言

SQL Server 2000 支援通過擴展存儲過程(XP)調用非托管 DLL 代碼。本文展示如何用 Delphi 編寫 DLL,實現接收 3 個字符串參數並逐行返回結果集的擴展存儲過程 xp_EpPackFile,涵蓋參數解析、列描述、行發送、完成標記的完整流程。

核心 API (MSODSApi.pas)

函數用途
srv_paraminfo獲取參數類型、長度、數據指針、是否 NULL
srv_rpcparams獲取 RPC 參數個數
srv_describe定義結果集列元數據 (名稱、類型、長度)
srv_setcoldata設置當前行某列數據指針
srv_sendrow發送當前行到客戶端
srv_senddone發送完成狀態 (行計數、更多結果標誌)

關鍵代碼實現

1. 字符串參數提取封裝

function GetParamStr(pSrvProc: SRV_PROC; Index: Integer; var Param: String): Integer;
var
  PType: Byte; cbMaxLen, ParaLen: DWORD; IsNULL: BOOL;
begin
  Result := NO_ERROR;
  srv_paraminfo(pSrvProc, Index, @PType, @cbMaxLen, @ParaLen, nil, @IsNULL);
  {僅處理字符串類型}
  if PType in [SRVTEXT, SRVVARCHAR, SRVCHAR, SRVNTEXT,
               SRVBIGVARCHAR, SRVBIGCHAR, SRVNVARCHAR, SRVNCHAR] then begin
    Param := '';
    if ParaLen > 0 then begin
      SetLength(Param, ParaLen);
      srv_paraminfo(pSrvProc, Index, @PType, @cbMaxLen, @ParaLen, @Param[1], @IsNULL);
    end;
  end else
    Result := -1; {類型不匹配}
end;

2. 擴展存儲過程入口函數

function EpPackFile(pSrvProc: SRV_PROC): Integer; cdecl;
var
  ls1, ls2, ls3: String;
  n: Integer;
begin
  Result := 1; {預設失敗}
  n := srv_rpcparams(pSrvProc);
  if n <> 3 then Exit; {參數個數不符}

  if GetParamStr(pSrvProc, 1, ls1) <> NO_ERROR then Exit;
  if GetParamStr(pSrvProc, 2, ls2) <> NO_ERROR then Exit;
  if GetParamStr(pSrvProc, 3, ls3) <> NO_ERROR then Exit;

  {描述結果集:1 列,名為 '參數',類型 SRVBIGVARCHAR}
  n := Length(ls1);
  srv_describe(pSrvProc, 1, '參數', SRV_NULLTERM, SRVBIGVARCHAR, n, SRVBIGVARCHAR, n, nil);

  {發送 3 行}
  srv_setcoldata(pSrvProc, 1, @ls1[1]); srv_sendrow(pSrvProc);
  srv_setcoldata(pSrvProc, 1, @ls2[1]); srv_sendrow(pSrvProc);
  srv_setcoldata(pSrvProc, 1, @ls3[1]); srv_sendrow(pSrvProc);

  {發送完成:SRV_DONE_COUNT(返回行計數) | SRV_DONE_MORE(無更多結果集)}
  srv_senddone(pSrvProc, (SRV_DONE_COUNT or SRV_DONE_MORE), 0, 1);
  Result := 0; {成功}
end;

3. 導出聲明

exports
  EpPackFile name 'xp_EpPackFile'; {導出名稱需與 sp_addextendedproc 一致}

SQL Server 部署與測試腳本

USE master;
IF OBJECT_ID('xp_EpPackFile') IS NOT NULL
  EXEC sp_dropextendedproc 'xp_EpPackFile';
EXEC sp_addextendedproc 'xp_EpPackFile', 'project1.dll'; {DLL 放入 Binn 目錄}
EXEC master..xp_EpPackFile 'aa', 'bb', 'cc'; {測試調用}
EXEC sp_dropextendedproc 'xp_EpPackFile';
DBCC FREEPROCCACHE; {清理計劃緩存}

預期結果集

參數
------
aa
bb
cc

關鍵注意事項

  1. 調用約定:入口函數必須聲明 cdecl(SQL Server 期望 C 調用約定)。
  2. 字符串編碼:SQL Server 2000 使用當前代碼頁(通常為 GBK/CP936),Delphi 字符串為 AnsiString 直接兼容;SQL Server 2005+ 建議使用 Unicode 版 API (SRVNVARCHAR、wchar_t*)。
  3. 內存管理:srv_setcoldata 傳遞的指針必須在 srv_sendrow 返回前保持有效,局部 String 變量在函數棧上滿足此條件。
  4. 線程安全:XP 在 SQL Server 進程內執行,全局變量需線程同步;盡量使用局部變量。
  5. 部署路徑:DLL 必須放在 SQL Server Binn 目錄,或在 sp_addextendedproc 指定完整路徑。

總結

掌握 srv_paraminfo 參數解析、srv_describe 列定義、srv_sendrow 行發送流程,即可用 Delphi 為 SQL Server 2000 構建高性能擴展存儲過程,實現文件操作、加密算法、外部 API 調用等 T-SQL 難以完成的功能。

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