加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

在SQLServer中调用外部扩展存储过程

发布时间:2020-12-12 15:58:47 所属栏目:MsSql教程 来源:网络整理
导读:? 1 、扩展存储过程的引入 首先,我们需要知道在 SQLServer ( 7.0 以上版本)中有一个扩展存储过程,名叫 sp_addextendedproc ,这是干什么用的呢,查它的帮助呀,不就知道了 J ,在 SQLServer 的帮助中是这样描述的:向 Microsoft SQL Server 注册新扩展存

?

1、扩展存储过程的引入

首先,我们需要知道在SQLServer7.0以上版本)中有一个扩展存储过程,名叫sp_addextendedproc,这是干什么用的呢,查它的帮助呀,不就知道了J,在SQLServer的帮助中是这样描述的:向 Microsoft SQL Server 注册新扩展存储过程的名称。语法为:sp_addextendedproc [@functname=] 'procedure',[@dllname=] 'dll'。由此我们知道,它的功能是把已经写好在外部DLL文件中的函数引入到SQLServer中,提供给其它SQL代码调用。其用法示例为:

USE master

GO

EXEC sp_addextendedproc 'xp_hello','c:/xp_hello.dll'

上面的语句表示把外部DLL文件 c:/xp_hello.dll 中的函数 xp_hello 引入到SQLServer中,在执行完上面的语句后,主库中就多了一个名为 xp_hello的扩展存储过程,我们在其它脚本中就可以调用此扩展存储过程了。有一点限定的是,sp_addextendedproc只能在master中执行,如果在其它库中调用xp_hello,需要加上master限定库名。

2、编写外部DLL文件

?????? 好了,我们知道了怎样在SQLServer中加载外部扩展存储过程,接下来,我们要做什么呢,对了,在外部DLL中怎样编写符合SQLServer调用的函数。在VC6以上版本中,我们在安装的目录下能找到一个VC++头文件,名叫srv.h,它主要是提供给编程人员编写SQLServer扩展存储过程用的,人们称它为ODS(Open Data Services)开放数据服务接口头文件,里面为众多的常量、结构体、以及从DLL文件opends60.dll中导入的众多函数。因此,我们在编写自己的DLL文件时,需要包含此头文件,然后编写符合SQLServer扩展存储过程要求的、声明导出方式为 cdecl约定(由调用者清除堆栈)的函数。编写示例:

SRVRETCODE xp_hello(SRV_PROC* pSrvProc)

{

??? srv_sendmsg(pSrvProc,SRV_MSG_ERROR,XP_HELLO_ERROR,SRV_INFO,1,

??????????? NULL,(DBUSMALLINT) __LINE__,

??????????? "Usage: exec xp_hello <@param1 output>",

??????????? SRV_NULLTERM);

??? srv_senddone(pSrvProc,(SRV_DONE_ERROR | SRV_DONE_MORE),0);

}

功能:这个示例显示怎样调用的输出字符串。上面的示例是在VC环境下开发的示例,实际上,只要遵守调用约定,用什么语言都可以实现,由于本人对Delphi比对VC熟悉,我在这里重点讲解在Delphi下的编写过程。

Delphi下开发,需要把VC下的头文件srv.h翻译为Delphi单元文件,便于调用,经过本人努力,已经翻译为OdsApi7.pas单元文件,内容如下:

{******************************************************************************}
{ @UnitName??? : OdsApi7?????????????????????????????????????????????????????? }
{ @Project???? : Algorism????????????????????????????????????????????????????? }
{ @Copyright?? : 1989 - 1999 Microsoft Corporation.??????????????????????????? }
{ @Translator? : 杨连山,yangls@263.net??????????????????????????????????????? }
{ @CreateDate? : 2005-6-22 14:37:53??????????????????????????????????????????? }
{ @LastUpdate? : 2005-6-22 14:37:53 by 杨连山????????????????????????????????? }
{????????????????????????????????????????????????????????????????????????????? }
{ @Description : ODS(Open Data Services)开放数据服务接口单元文件,转换自VC7下的}
{??????????????? srv.h头文件.????????????????????????????????????????????????? }
{????????????????????????????????????????????????????????????????????????????? }
{ @Comment???? : 转换者: 杨连山??????????????????????????????????????????????? }
{????????????? 1、您可以免费使用和分发本单元文件,但不能作为商业应用之全部或部分.}
{????????????? 2、在使用中如造成任何损失,本转换者概不负责.??????????????????? }
{????????????? 3、转换者不保证本单元转换全部正确,如您发现或修正后,有义务反馈 }
{???????????????? 最新版给转换者. 发到 yangls@263.net????????????????????????? }
{????????????? 4、请保留以上说明信息?????????????????????????????????????????? }
{????????????????????????????????????????????????????????????????????????????? }
{ @History???? : 2005-06-22 杨连山转换???????????????????????????????????????? }
{????????????????????????????????????????????????????????????????????????????? }
{******************************************************************************}
unit OdsApi7;

interface

{$DEFINE DYNAMIC_LINK}

{$IFDEF DYNAMIC_LINK}
? {$STACKFRAMES ON}
? {$WARNINGS OFF}
{$ENDIF}

uses Windows;

// ODS uses pack(4) on all CPU types
{$ALIGN ON}
{$MINENUMSIZE 4}

// Formats of data types
type
? DBBOOL????? = System.LongBool;
? DBBYTE????? = System.BYTE;
? DBTINYINT?? = System.Shortint;
? DBSMALLINT? = System.SmallInt;
? DBUSMALLINT = System.Word;
? DBINT?????? = System.Integer;
? DBCHAR????? = System.Char;
? PDBCHAR???? = ^DBChar;
? DBBINARY??? = System.BYTE;
? DBBIT?????? = (_0,_1);
? DBFLT8????? = System.Double;
?
? TDBDATETIME = record??? // Format for SRVDATETIME
??? dtdays: Longint;????? // number of days since 1/1/1900
??? dttime: LongWord;???? // number 300th second since mid
? end;

? TDBMONEY = record?????? // Format for SRVMONEY
??? mnyhigh: Longint;
??? mnylow: LongWord;
? end;
?
? DBFLT4 = Single;
? DBMONEY4 = Longint;??

? TDBDATETIME4 = record?? // Format for SRVDATETIM4
??? numdays: Word;??????? // number of days since 1/1/1900
??? nummins: Word;??????? // number of minutes sicne midnight???????
? end;
?
const
? MAXNUMERICLEN?= 16;

type
? TDBNUMERIC = record???? // Format for SRVNUMERIC,SRVNUMERICN,SRVDECIMAL,SRVDECIMALN
? ?precision: BYTE;
? ?scale: BYTE;
? ?sign: BYTE;
? ?val: array[0..MAXNUMERICLEN - 1] of BYTE;
? end;?
? TDBDECIMAL = TDBNUMERIC;
?
// Constants used by APIs
const
? // Type Tokens
? SRV_TDS_NULL???????? = BYTE($1f);
? SRV_TDS_TEXT???????? = BYTE($23);
? SRV_TDS_GUID???????? = BYTE($24);
? SRV_TDS_VARBINARY??? = BYTE($25);
? SRV_TDS_INTN???????? = BYTE($26);
? SRV_TDS_VARCHAR????? = BYTE($27);
? SRV_TDS_BINARY?????? = BYTE($2d);
? SRV_TDS_IMAGE??????? = BYTE($22);
? SRV_TDS_CHAR???????? = BYTE($2f);
? SRV_TDS_INT1???????? = BYTE($30);
? SRV_TDS_BIT????????? = BYTE($32);
? SRV_TDS_INT2???????? = BYTE($34);
? SRV_TDS_DECIMAL????? = BYTE($37);
? SRV_TDS_INT4???????? = BYTE($38);
? SRV_TDS_DATETIM4???? = BYTE($3a);
? SRV_TDS_FLT4???????? = BYTE($3b);
? SRV_TDS_MONEY??????? = BYTE($3c);
? SRV_TDS_DATETIME???? = BYTE($3d);
? SRV_TDS_FLT8???????? = BYTE($3e);
? SRV_TDS_NUMERIC????? = BYTE($3f);
? SRV_TDS_NTEXT?????? = BYTE($63);
? SRV_TDS_BITN?????? = BYTE($68);
? SRV_TDS_DECIMALN???? = BYTE($6a);
? SRV_TDS_NUMERICN???? = BYTE($6c);
? SRV_TDS_FLTN???????? = BYTE($6d);
? SRV_TDS_MONEYN?????? = BYTE($6e);
? SRV_TDS_DATETIMN???? = BYTE($6f);
? SRV_TDS_MONEY4?????? = BYTE($7a);
? SRV_TDS_BIGVARBINARY = BYTE($A5);
? SRV_TDS_BIGVARCHAR?? = BYTE($A7);
? SRV_TDS_BIGBINARY??? = BYTE($AD);
? SRV_TDS_BIGCHAR????? = BYTE($AF);
? SRV_TDS_NVARCHAR??? = BYTE($e7);
? SRV_TDS_NCHAR?????? = BYTE($ef);
?
? // Datatypes
? // Also: values of symbol parameter to srv_symbol when type = SRV_DATATYPE
? SRVNULL???????????? = SRV_TDS_NULL;
? SRVTEXT???????????? = SRV_TDS_TEXT;
? SRVGUID???????????? = SRV_TDS_GUID;
? SRVVARBINARY??????? = SRV_TDS_VARBINARY;
? SRVINTN???????????? = SRV_TDS_INTN;
? SRVVARCHAR????????? = SRV_TDS_VARCHAR;
? SRVBINARY?????????? = SRV_TDS_BINARY;
? SRVIMAGE??????????? = SRV_TDS_IMAGE;
? SRVCHAR???????????? = SRV_TDS_CHAR;
? SRVINT1???????????? = SRV_TDS_INT1;
? SRVBIT????????????? = SRV_TDS_BIT;
? SRVINT2???????????? = SRV_TDS_INT2;
? SRVDECIMAL???????? = SRV_TDS_DECIMAL;
? SRVINT4???????????? = SRV_TDS_INT4;
? SRVDATETIM4???????? = SRV_TDS_DATETIM4;
? SRVFLT4???????????? = SRV_TDS_FLT4;
? SRVMONEY??????????? = SRV_TDS_MONEY;
? SRVDATETIME???????? = SRV_TDS_DATETIME;
? SRVFLT8???????????? = SRV_TDS_FLT8;
? SRVNUMERIC???????? = SRV_TDS_NUMERIC;
? SRVNTEXT?????????? = SRV_TDS_NTEXT;
? SRVBITN??????????? = SRV_TDS_BITN;
? SRVDECIMALN???????? = SRV_TDS_DECIMALN;
? SRVNUMERICN???????? = SRV_TDS_NUMERICN;
? SRVFLTN???????????? = SRV_TDS_FLTN;
? SRVMONEYN?????????? = SRV_TDS_MONEYN;
? SRVDATETIMN???????? = SRV_TDS_DATETIMN;
? SRVMONEY4?????????? = SRV_TDS_MONEY4;
? SRVBIGVARBINARY???? = SRV_TDS_BIGVARBINARY;
? SRVBIGVARCHAR?????? = SRV_TDS_BIGVARCHAR;
? SRVBIGBINARY??????? = SRV_TDS_BIGBINARY;
? SRVBIGCHAR????????? = SRV_TDS_BIGCHAR;
? SRVNVARCHAR???????? = SRV_TDS_NVARCHAR;
? SRVNCHAR?????????? = SRV_TDS_NCHAR;

? // 注: 为了不与其它名字冲突,在下面原常量前加了 CONST_?
? // values for srv_symbol
? CONST_SRV_ERROR????? = 0;
? CONST_SRV_DONE?????? = 1;
? CONST_SRV_DATATYPE?? = 2;
? CONST_SRV_EVENT????? = 4;

? // values for srv_symbol symb
? SRV_ENO_OS_ERR???? = 0;
? SRV_INFO?????????? = 1;
? SRV_FATAL_PROCESS? = 10;
? SRV_FATAL_SERVER?? = 19;

? // Types of server events
? // Also: values for srv_symbol symbol parameter,when type = SRV_EVENT
? SRV_CONTINUE??????????? = 0;
? SRV_LANGUAGE??????????? = 1;
? SRV_CONNECT???????????? = 2;
? SRV_RPC???????????????? = 3;
? SRV_RESTART???????????? = 4;
? SRV_DISCONNECT????????? = 5;
? SRV_ATTENTION?????????? = 6;
? SRV_SLEEP?????????????? = 7;
? SRV_START?????????????? = 8;
? SRV_STOP??????????????? = 9;
? SRV_EXIT??????????????? = 10;
? SRV_CANCEL????????????? = 11;
? SRV_SETUP?????????????? = 12;
? SRV_CLOSE?????????????? = 13;
? SRV_PRACK?????????????? = 14;
? SRV_PRERROR???????????? = 15;
? SRV_ATTENTION_ACK?????? = 16;
? SRV_CONNECT_V7???????? = 16;?// TDS type for TDS 7 clients.? Overloaded with SRV_ATTENTION_ACK
? SRV_SKIP????????????? = 17;
? SRV_TRANSMGR?????????? = 18;
? SRV_OLEDB?????????????? = 20;
? SRV_INTERNAL_HANDLER??? = 99;
? SRV_PROGRAMMER_DEFINED? = 100;
?
? // values for srv_config option parameter
? SRV_CONNECTIONS??????? = 1;
? SRV_LOGFILE??????????? = 2;
? SRV_STACKSIZE????????? = 3;
? SRV_REMOTE_ACCESS????? = 7;
? SRV_REMOTE_CONNECTIONS = 9;
? SRV_MAX_PACKETS??????? = 10;
? SRV_MAXWORKINGTHREADS? = 11;
? SRV_MINWORKINGTHREADS? = 12;
? SRV_THREADTIMEOUT???? = 13;
? SRV_MAX_PACKETSIZE?? = 17;
? SRV_THREADPRIORITY?? = 18;
? SRV_ANSI_CODEPAGE???? = 19;
? SRV_DEFAULT_PACKETSIZE = 26;
? SRV_PASSTHROUGH????? = 27;
?
? // vlaues for srv_config value parameter when option = SRV_THREADPRIORITY
? SRV_PRIORITY_LOW????? = THREAD_PRIORITY_LOWEST;
? SRV_PRIORITY_NORMAL?? = THREAD_PRIORITY_NORMAL;
? SRV_PRIORITY_HIGH???? = THREAD_PRIORITY_HIGHEST;
? SRV_PRIORITY_CRITICAL = THREAD_PRIORITY_TIME_CRITICAL;
?
? // values for srv_sfield field parameter
? SRV_SERVERNAME???????? = 0;
? SRV_VERSION??????????? = 6;
?
? // Length to indicate string is null terminated
? SRV_NULLTERM?? = -1;
?
? // values of msgtype parameter to srv_sendmsg
? SRV_MSG_INFO??? = 1;
? SRV_MSG_ERROR?? = 2;
?
? // values of status parameter to srv_senddone
? // Also: values for symbol parameters to srv_symbol when type = SRV_DONE
? SRV_DONE_FINAL?????? = Word($0000);
? SRV_DONE_MORE???????? = Word($0001);
? SRV_DONE_ERROR?????? = Word($0002);
? SRV_DONE_COUNT?????? = Word($0010);
? SRV_DONE_RPC_IN_BATCH?? = Word($0080);
?
? // return values of srv_paramstatus
? SRV_PARAMRETURN??? = $0001;
? SRV_PARAMDEFAULT??? = $0002;

? // return values of srv_rpcoptions
? SRV_RECOMPILE??? = $0001;
? SRV_NOMETADATA??= $0002;
?
? // values of field parameter to srv_pfield
? //#define SRV_LANGUAGE 1?? already defined above
? //#define SRV_EVENT??? 4?? already defined above
? SRV_SPID?????????? = 10;
? SRV_NETSPID???????? = 11;
? SRV_TYPE?????????? = 12;
? SRV_STATUS???????? = 13;
? SRV_RMTSERVER??????? = 14;
? SRV_HOST????????? = 15;
? SRV_USER????????? = 16;
? SRV_PWD?????????? = 17;
? SRV_CPID????????? = 18;
? SRV_APPLNAME??????? = 19;
? SRV_TDS?????????? = 20;
? SRV_CLIB????????? = 21;
? SRV_LIBVERS???????? = 22;
? SRV_ROWSENT???????? = 23;
? SRV_BCPFLAG???????? = 24;
? SRV_NATLANG???????? = 25;
? SRV_PIPEHANDLE????? = 26;
? SRV_NETWORK_MODULE??? = 27;
? SRV_NETWORK_VERSION?? = 28;
? SRV_NETWORK_CONNECTION = 29;
? SRV_LSECURE???????? = 30;
? SRV_SAXP?????????? = 31;
? SRV_UNICODE_USER???? = 33;
? SRV_UNICODE_PWD????? = 35;
? SRV_SPROC_CODEPAGE???? = 36;
?
? // return value of SRV_TDSVERSION macro
? SRV_TDS_NONE? = 0;
? SRV_TDS_2_0?? = 1;
? SRV_TDS_3_4?? = 2;
? SRV_TDS_4_2?? = 3;
? SRV_TDS_6_0?? = 4;
? SRV_TDS_7_0?? = 5;

// Return values from APIs?
type
? SRVRETCODE = Integer;??????? // SUCCEED or FAIL
? RETCODE??? = Integer;
?
const
? SUCCEED???? = 1;?? // Successful return value
? FAIL??????? = 0;?? // Unsuccessful return value
?
? SRV_DUPLICATE_HANDLER?= 2;?// additional return value for srv_pre/post_handle
?
//------------------------------------------------
//PreDeclare structures
//
type
? PSRV_SERVER = ^TSRV_SERVER;
? TSRV_SERVER = record
??? //...
? end;

? PSRV_CONFIG = ^TSRV_CONFIG;
? TSRV_CONFIG = record
??? connections: UINT;????????? // maximum allowed client connections
??? //...?
? end;

? PSRV_PROC = ^TSRV_PROC;
? TSRV_PROC = record
??? tdsversion: WORD;?? // version of tds detected from client,0x3400 = 3.4,0x4000 = 4.0
??? //...
? end;

type
? PPointer = ^Pointer;
? THandler = function(handle: Pointer): Integer; cdecl;
? TErrHandler = function(server: PSRV_SERVER; srvproc: PSRV_PROC; srverror: Integer;
??? serverity,state: BYTE; oserrnum: Integer; errtext: PChar; errtextlen: Integer;
??? oserrtext: PChar; oserrtextlen: Integer): Integer; cdecl;??

//------------------------------------------------
// ODS MACROs & APIs

// Describing and sending a result set
function srv_describe(srvproc: PSRV_PROC; colnumber: Integer; columnname: PChar;
? namelen: Integer; desttype,destlen,srctype,srclen: Integer; srcdata: Pointer): Integer; cdecl;
function srv_setutype(srvproc: PSRV_PROC; column: Integer; usertype: Integer): Integer; cdecl;
function srv_setcoldata(srvproc: PSRV_PROC; column: Integer; data: Pointer): Integer; cdecl;
function srv_setcollen(srvproc: PSRV_PROC; column,len: Integer): Integer; cdecl;
function srv_sendrow(srvproc: PSRV_PROC): Integer; cdecl;
function srv_senddone(srvproc: PSRV_PROC; status,curcmd: Word; count: Integer): Integer; cdecl;

// Dealing with Extended Procedure parameters
function srv_rpcparams(srvproc: PSRV_PROC): Integer; cdecl;
function srv_paraminfo(srvproc: PSRV_PROC; n: Integer; var bType: BYTE;
? var cbMaxLen,cbActualLen: Integer; Data: Pointer; var fNull: BOOL): Integer; cdecl;
function srv_paramsetoutput(srvproc: PSRV_PROC; n: Integer; data: Pointer;
? uvalue: LongWord; bvalue: BOOL): Integer; cdecl;
function srv_paramdata(srvproc: PSRV_PROC; n: Integer): Pointer; cdecl;
function srv_paramlen(srvproc: PSRV_PROC; n: Integer): Integer; cdecl;
function srv_parammaxlen(srvproc: PSRV_PROC; n: Integer): Integer; cdecl;
function srv_paramtype(srvproc: PSRV_PROC; n: Integer): Integer; cdecl;
function srv_paramset(srvproc: PSRV_PROC; n: Integer; data: Pointer; len: Integer): Integer; cdecl;
function srv_paramname(srvproc: PSRV_PROC; n: Integer; var len: Integer): PChar; cdecl;
function srv_paramnumber(srvproc: PSRV_PROC; name: PChar; len: Integer): Integer; cdecl;

//--------------------------------------------------------------
// The rest of these APIs are still supported,in SQL Server 7.0,
// but may not be supported after SQL Server 7.0

function srv_getconfig(server: PSRV_SERVER): PSRV_CONFIG; cdecl;
function srv_getserver(srvproc: PSRV_PROC): PSRV_SERVER; cdecl;
function srv_got_attention(srvproc: PSRV_PROC): BOOL; cdecl;
function srv_eventdata(srvproc: PSRV_PROC): Pointer; cdecl;

// Memory
function srv_alloc(ulSize: Integer): Pointer; cdecl;
function srv_bmove(from,pto: Pointer; count: Integer): Integer; cdecl;
function srv_bzero(location: Pointer; count: Integer): Integer; cdecl;
function srv_free(ptr: Pointer): Integer; cdecl;

function srv_config(config: PSRV_CONFIG; option: Integer; value: PChar;
? valuelen: Integer): Integer; cdecl;
function srv_config_alloc(): PSRV_CONFIG; cdecl;??

function srv_convert(srvproc: PSRV_PROC; srctype: Integer; src: Pointer; srclen: Integer;
? desttype: Integer; dest: Pointer; destlen: Integer): Integer; cdecl;
?
function srv_errhandle(Errhandler: TErrHandler): TErrHandler; cdecl;

function srv_event(srvproc: PSRV_PROC; event: Integer; data: PBYTE): Integer; cdecl;

function srv_getuserdata(srvproc: PSRV_PROC): Pointer; cdecl;

function srv_getbindtoken(srvproc: PSRV_PROC; token_buf: PChar): Integer; cdecl;

function srv_getdtcxact(srvproc: PSRV_PROC; ppv: PPointer): Integer; cdecl;

function srv_handle(server: PSRV_SERVER; event: Integer; handler: THandler): THandler; cdecl;

function srv_impersonate_client(srvproc: PSRV_PROC): Integer; cdecl;

function srv_init(config: PSRV_CONFIG; connectname: PChar; namelen: Integer): PSRV_SERVER; cdecl;

function srv_iodead(srvproc: PSRV_PROC): BOOL; cdecl;

function srv_langcpy(srvproc: PSRV_PROC; start,nbytes: LongWord; buffer: PChar): LongWord; cdecl;
function srv_langlen(srvproc: PSRV_PROC): LongWord; cdecl;
function srv_langptr(srvproc: PSRV_PROC): Pointer; cdecl;

function srv_log(server: PSRV_SERVER; datestamp: BOOL; msg: PChar; msglen: Integer): Integer; cdecl;

function srv_paramstatus(srvproc: PSRV_PROC; n: Integer): Integer; cdecl;

function srv_pfield(srvproc: PSRV_PROC; field: Integer; var len: Integer): PChar; cdecl;

function srv_returnval(srvproc: PSRV_PROC; valuename: PChar; len: Integer; status: BYTE;
? itype,maxlen,datalen: Integer; value: Pointer): Integer; cdecl;

function srv_revert_to_self(srvproc: PSRV_PROC): Integer; cdecl;

function srv_rpcdb(srvproc: PSRV_PROC; var len: Integer): PChar; cdecl;
function srv_rpcname(srvproc: PSRV_PROC; var len: Integer): PChar; cdecl;
function srv_rpcnumber(srvproc: PSRV_PROC): Integer; cdecl;
function srv_rpcoptions(srvproc: PSRV_PROC): Word; cdecl;
function srv_rpcowner(srvproc: PSRV_PROC; var len: Integer): PChar; cdecl;

function srv_run(server: PSRV_SERVER): Integer; cdecl;

function srv_sendmsg(srvproc: PSRV_PROC; msgtype: Integer; msgnum: Integer; msgclass: Shortint;
? state: Shortint; rpcname: PChar; rpcnamelen: Integer; linenum: Word;
? message: PChar; msglen: Integer): Integer; cdecl;
function srv_ansi_sendmsg(srvproc: PSRV_PROC; msgtype: Integer; msgnum: Integer;
? msgclass,state: Shortint; rpcname: PChar; rpcnamelen: Integer; linenum: Word;
? message: PChar; msglen: Integer): Integer; cdecl;

function srv_sendstatus(srvproc: PSRV_PROC; status: Integer): Integer; cdecl;?

function srv_setuserdata(srvproc: PSRV_PROC; ptr: Pointer): Integer; cdecl;

function srv_sfield(server: PSRV_SERVER; field: Integer; var len: Integer): PChar; cdecl;

function srv_symbol(itype,symbol: Integer; var len: Integer): PChar; cdecl;

function srv_tdsversion(srvproc: PSRV_PROC): Integer; cdecl;

function srv_writebuf(srvproc: PSRV_PROC; ptr: Pointer; count: WORD): Integer; cdecl;

function srv_willconvert(srctype,desttype: Integer): BOOL; cdecl;

procedure srv_ackattention(srvproc: PSRV_PROC); cdecl;

function srv_terminatethread(srvproc: PSRV_PROC): Integer; cdecl;

function srv_sendstatistics(srvproc: PSRV_PROC): Integer; cdecl;

function srv_clearstatistics(srvproc: PSRV_PROC): Integer; cdecl;

function srv_setevent(server: PSRV_SERVER; event: Integer): Integer; cdecl;

function srv_message_handler(srvproc: PSRV_PROC; errornum: Integer; serverity: BYTE;
? state: BYTE; oserrnum: Integer; errtext: PChar; errtextlen: Integer; oserrtext: PChar;
? oserrtextlen: Integer): Integer; cdecl;

function srv_pre_handle(server: PSRV_SERVER; srvproc: PSRV_PROC; event: Integer;
? handler: THandler; remove: BOOL): Integer; cdecl;
function srv_post_handle(server: PSRV_SERVER; srvproc: PSRV_PROC; event: Integer;
? handler: THandler; remove: BOOL): Integer; cdecl;??

function srv_post_completion_queue(srvproc: PSRV_PROC; inbuf: PChar;
? inbuflen: Integer): Integer; cdecl;

function srv_IgnoreAnsiToOem(srvproc: PSRV_PROC; bTF: BOOL): Integer; cdecl;

// ODS_VERSION
const
? SS_MAJOR_VERSION??? = 7;
? SS_MINOR_VERSION??? = 00;
? SS_LEVEL_VERSION??? = 0000;
? SS_MINIMUM_VERSION? = '7.00.00.0000';
? function ODS_VERSION(): Integer;

implementation

uses SysUtils;

const
? opendsdll = 'opends60.dll';

procedure GetProcedureAddress(var P: Pointer; const ModuleName,ProcName: string);
var
? ModuleHandle: HMODULE;
begin
? if not Assigned(P) then
? begin
??? ModuleHandle := GetModuleHandle(PChar(ModuleName));
??? if ModuleHandle = 0 then
??? begin
????? ModuleHandle := LoadLibrary(PChar(ModuleName));
????? if ModuleHandle = 0 then
??????? raise Exception.Create('Library not found: ' + ModuleName);
??? end;
??? P := GetProcAddress(ModuleHandle,PChar(ProcName));
??? if not Assigned(P) then
????? raise Exception.Create('Function not found: ' + ModuleName + '.' + ProcName);
? end;
end;

{------------------------------------------------------------------------------}
// Describing and sending a result set

{$IFDEF DYNAMIC_LINK}
var
? _srv_describe: Pointer;
function srv_describe;
begin
? GetProcedureAddress(_srv_describe,opendsdll,'srv_describe');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_describe]
? end;
end;
{$ELSE}
function srv_describe; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_setutype: Pointer;
function srv_setutype;
begin
? GetProcedureAddress(_srv_setutype,'srv_setutype');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_setutype]
? end;
end;
{$ELSE}
function srv_setutype; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_setcoldata: Pointer;
function srv_setcoldata;
begin
? GetProcedureAddress(_srv_setcoldata,'srv_setcoldata');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_setcoldata]
? end;
end;
{$ELSE}
function srv_setcoldata; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_setcollen: Pointer;
function srv_setcollen;
begin
? GetProcedureAddress(_srv_setcollen,'srv_setcollen');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_setcollen]
? end;
end;
{$ELSE}
function srv_setcollen; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_sendrow: Pointer;
function srv_sendrow;
begin
? GetProcedureAddress(_srv_sendrow,'srv_sendrow');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_sendrow]
? end;
end;
{$ELSE}
function srv_sendrow; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_senddone: Pointer;
function srv_senddone;
begin
? GetProcedureAddress(_srv_senddone,'srv_senddone');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_senddone]
? end;
end;
{$ELSE}
function srv_senddone; external opendsdll;
{$ENDIF}

// Dealing with Extended Procedure parameters
{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcparams: Pointer;
function srv_rpcparams;
begin
? GetProcedureAddress(_srv_rpcparams,'srv_rpcparams');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcparams]
? end;
end;
{$ELSE}
function srv_rpcparams; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paraminfo: Pointer;
function srv_paraminfo;
begin
? GetProcedureAddress(_srv_paraminfo,'srv_paraminfo');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paraminfo]
? end;
end;
{$ELSE}
function srv_paraminfo; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramsetoutput: Pointer;
function srv_paramsetoutput;
begin
? GetProcedureAddress(_srv_paramsetoutput,'srv_paramsetoutput');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramsetoutput]
? end;
end;
{$ELSE}
function srv_paramsetoutput; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramdata: Pointer;
function srv_paramdata;
begin
? GetProcedureAddress(_srv_paramdata,'srv_paramdata');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramdata]
? end;
end;
{$ELSE}
function srv_paramdata; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramlen: Pointer;
function srv_paramlen;
begin
? GetProcedureAddress(_srv_paramlen,'srv_paramlen');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramlen]
? end;
end;
{$ELSE}
function srv_paramlen; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_parammaxlen: Pointer;
function srv_parammaxlen;
begin
? GetProcedureAddress(_srv_parammaxlen,'srv_parammaxlen');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_parammaxlen]
? end;
end;
{$ELSE}
function srv_parammaxlen; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramtype: Pointer;
function srv_paramtype;
begin
? GetProcedureAddress(_srv_paramtype,'srv_paramtype');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramtype]
? end;
end;
{$ELSE}
function srv_paramtype; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramset: Pointer;
function srv_paramset;
begin
? GetProcedureAddress(_srv_paramset,'srv_paramset');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramset]
? end;
end;
{$ELSE}
function srv_paramset; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramname: Pointer;
function srv_paramname;
begin
? GetProcedureAddress(_srv_paramname,'srv_paramname');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramname]
? end;
end;
{$ELSE}
function srv_paramname; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramnumber: Pointer;
function srv_paramnumber;
begin
? GetProcedureAddress(_srv_paramnumber,'srv_paramnumber');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramnumber]
? end;
end;
{$ELSE}
function srv_paramnumber; external opendsdll;
{$ENDIF}

//--------------------------------------------------------------
// The rest of these APIs are still supported,
// but may not be supported after SQL Server 7.0

{$IFDEF DYNAMIC_LINK}
var
? _srv_getconfig: Pointer;
function srv_getconfig;
begin
? GetProcedureAddress(_srv_getconfig,'srv_getconfig');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_getconfig]
? end;
end;
{$ELSE}
function srv_getconfig; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_getserver: Pointer;
function srv_getserver;
begin
? GetProcedureAddress(_srv_getserver,'srv_getserver');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_getserver]
? end;
end;
{$ELSE}
function srv_getserver; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_got_attention: Pointer;
function srv_got_attention;
begin
? GetProcedureAddress(_srv_got_attention,'srv_got_attention');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_got_attention]
? end;
end;
{$ELSE}
function srv_got_attention; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_eventdata: Pointer;
function srv_eventdata;
begin
? GetProcedureAddress(_srv_eventdata,'srv_eventdata');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_eventdata]
? end;
end;
{$ELSE}
function srv_eventdata; external opendsdll;
{$ENDIF}

// Memory
{$IFDEF DYNAMIC_LINK}
var
? _srv_alloc: Pointer;
function srv_alloc;
begin
? GetProcedureAddress(_srv_alloc,'srv_alloc');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_alloc]
? end;
end;
{$ELSE}
function srv_alloc; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_bmove: Pointer;
function srv_bmove;
begin
? GetProcedureAddress(_srv_bmove,'srv_bmove');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_bmove]
? end;
end;
{$ELSE}
function srv_bmove; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_bzero: Pointer;
function srv_bzero;
begin
? GetProcedureAddress(_srv_bzero,'srv_bzero');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_bzero]
? end;
end;
{$ELSE}
function srv_bzero; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_free: Pointer;
function srv_free;
begin
? GetProcedureAddress(_srv_free,'srv_free');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_free]
? end;
end;
{$ELSE}
function srv_free; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_config: Pointer;
function srv_config;
begin
? GetProcedureAddress(_srv_config,'srv_config');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_config]
? end;
end;
{$ELSE}
function srv_config; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_config_alloc: Pointer;
function srv_config_alloc;
begin
? GetProcedureAddress(_srv_config_alloc,'srv_config_alloc');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_config_alloc]
? end;
end;
{$ELSE}
function srv_config_alloc; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_convert: Pointer;
function srv_convert;
begin
? GetProcedureAddress(_srv_convert,'srv_convert');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_convert]
? end;
end;
{$ELSE}
function srv_convert; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_errhandle: Pointer;
function srv_errhandle;
begin
? GetProcedureAddress(_srv_errhandle,'srv_errhandle');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_errhandle]
? end;
end;
{$ELSE}
function srv_errhandle; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_event: Pointer;
function srv_event;
begin
? GetProcedureAddress(_srv_event,'srv_event');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_event]
? end;
end;
{$ELSE}
function srv_event; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_getuserdata: Pointer;
function srv_getuserdata;
begin
? GetProcedureAddress(_srv_getuserdata,'srv_getuserdata');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_getuserdata]
? end;
end;
{$ELSE}
function srv_getuserdata; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_getbindtoken: Pointer;
function srv_getbindtoken;
begin
? GetProcedureAddress(_srv_getbindtoken,'srv_getbindtoken');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_getbindtoken]
? end;
end;
{$ELSE}
function srv_getbindtoken; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_getdtcxact: Pointer;
function srv_getdtcxact;
begin
? GetProcedureAddress(_srv_getdtcxact,'srv_getdtcxact');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_getdtcxact]
? end;
end;
{$ELSE}
function srv_getdtcxact; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_handle: Pointer;
function srv_handle;
begin
? GetProcedureAddress(_srv_handle,'srv_handle');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_handle]
? end;
end;
{$ELSE}
function srv_handle; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_impersonate_client: Pointer;
function srv_impersonate_client;
begin
? GetProcedureAddress(_srv_impersonate_client,'srv_impersonate_client');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_impersonate_client]
? end;
end;
{$ELSE}
function srv_impersonate_client; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_init: Pointer;
function srv_init;
begin
? GetProcedureAddress(_srv_init,'srv_init');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_init]
? end;
end;
{$ELSE}
function srv_init; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_iodead: Pointer;
function srv_iodead;
begin
? GetProcedureAddress(_srv_iodead,'srv_iodead');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_iodead]
? end;
end;
{$ELSE}
function srv_iodead; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_langcpy: Pointer;
function srv_langcpy;
begin
? GetProcedureAddress(_srv_langcpy,'srv_langcpy');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_langcpy]
? end;
end;
{$ELSE}
function srv_langcpy; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_langlen: Pointer;
function srv_langlen;
begin
? GetProcedureAddress(_srv_langlen,'srv_langlen');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_langlen]
? end;
end;
{$ELSE}
function srv_langlen; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_langptr: Pointer;
function srv_langptr;
begin
? GetProcedureAddress(_srv_langptr,'srv_langptr');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_langptr]
? end;
end;
{$ELSE}
function srv_langptr; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_log: Pointer;
function srv_log;
begin
? GetProcedureAddress(_srv_log,'srv_log');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_log]
? end;
end;
{$ELSE}
function srv_log; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_paramstatus: Pointer;
function srv_paramstatus;
begin
? GetProcedureAddress(_srv_paramstatus,'srv_paramstatus');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_paramstatus]
? end;
end;
{$ELSE}
function srv_paramstatus; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_pfield: Pointer;
function srv_pfield;
begin
? GetProcedureAddress(_srv_pfield,'srv_pfield');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_pfield]
? end;
end;
{$ELSE}
function srv_pfield; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_returnval: Pointer;
function srv_returnval;
begin
? GetProcedureAddress(_srv_returnval,'srv_returnval');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_returnval]
? end;
end;
{$ELSE}
function srv_returnval; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_revert_to_self: Pointer;
function srv_revert_to_self;
begin
? GetProcedureAddress(_srv_revert_to_self,'srv_revert_to_self');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_revert_to_self]
? end;
end;
{$ELSE}
function srv_revert_to_self; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcdb: Pointer;
function srv_rpcdb;
begin
? GetProcedureAddress(_srv_rpcdb,'srv_rpcdb');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcdb]
? end;
end;
{$ELSE}
function srv_rpcdb; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcname: Pointer;
function srv_rpcname;
begin
? GetProcedureAddress(_srv_rpcname,'srv_rpcname');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcname]
? end;
end;
{$ELSE}
function srv_rpcname; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcnumber: Pointer;
function srv_rpcnumber;
begin
? GetProcedureAddress(_srv_rpcnumber,'srv_rpcnumber');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcnumber]
? end;
end;
{$ELSE}
function srv_rpcnumber; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcoptions: Pointer;
function srv_rpcoptions;
begin
? GetProcedureAddress(_srv_rpcoptions,'srv_rpcoptions');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcoptions]
? end;
end;
{$ELSE}
function srv_rpcoptions; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_rpcowner: Pointer;
function srv_rpcowner;
begin
? GetProcedureAddress(_srv_rpcowner,'srv_rpcowner');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_rpcowner]
? end;
end;
{$ELSE}
function srv_rpcowner; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_run: Pointer;
function srv_run;
begin
? GetProcedureAddress(_srv_run,'srv_run');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_run]
? end;
end;
{$ELSE}
function srv_run; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_sendmsg: Pointer;
function srv_sendmsg;
begin
? GetProcedureAddress(_srv_sendmsg,'srv_sendmsg');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_sendmsg]
? end;
end;
{$ELSE}
function srv_sendmsg; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_ansi_sendmsg: Pointer;
function srv_ansi_sendmsg;
begin
? GetProcedureAddress(_srv_ansi_sendmsg,'srv_ansi_sendmsg');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_ansi_sendmsg]
? end;
end;
{$ELSE}
function srv_ansi_sendmsg; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_sendstatus: Pointer;
function srv_sendstatus;
begin
? GetProcedureAddress(_srv_sendstatus,'srv_sendstatus');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_sendstatus]
? end;
end;
{$ELSE}
function srv_sendstatus; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_setuserdata: Pointer;
function srv_setuserdata;
begin
? GetProcedureAddress(_srv_setuserdata,'srv_setuserdata');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_setuserdata]
? end;
end;
{$ELSE}
function srv_setuserdata; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_sfield: Pointer;
function srv_sfield;
begin
? GetProcedureAddress(_srv_sfield,'srv_sfield');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_sfield]
? end;
end;
{$ELSE}
function srv_sfield; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_symbol: Pointer;
function srv_symbol;
begin
? GetProcedureAddress(_srv_symbol,'srv_symbol');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_symbol]
? end;
end;
{$ELSE}
function srv_symbol; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_tdsversion: Pointer;
function srv_tdsversion;
begin
? GetProcedureAddress(_srv_tdsversion,'srv_tdsversion');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_tdsversion]
? end;
end;
{$ELSE}
function srv_tdsversion; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_writebuf: Pointer;
function srv_writebuf;
begin???
? GetProcedureAddress(_srv_writebuf,'srv_writebuf');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_writebuf]
? end;
end;
{$ELSE}
function srv_writebuf; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_willconvert: Pointer;
function srv_willconvert;
begin
? GetProcedureAddress(_srv_willconvert,'srv_willconvert');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_willconvert]
? end;
end;
{$ELSE}
function srv_willconvert; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_ackattention: Pointer;
procedure srv_ackattention;
begin
? GetProcedureAddress(_srv_ackattention,'srv_ackattention');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_ackattention]
? end;
end;
{$ELSE}
procedure srv_ackattention; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_terminatethread: Pointer;
function srv_terminatethread;
begin
? GetProcedureAddress(_srv_terminatethread,'srv_terminatethread');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_terminatethread]
? end;
end;
{$ELSE}
function srv_terminatethread; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_sendstatistics: Pointer;
function srv_sendstatistics;
begin
? GetProcedureAddress(_srv_sendstatistics,'srv_sendstatistics');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_sendstatistics]
? end;
end;
{$ELSE}
function srv_sendstatistics; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_clearstatistics: Pointer;
function srv_clearstatistics;
begin
? GetProcedureAddress(_srv_clearstatistics,'srv_clearstatistics');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_clearstatistics]
? end;
end;
{$ELSE}
function srv_clearstatistics; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_setevent: Pointer;
function srv_setevent;
begin
? GetProcedureAddress(_srv_setevent,'srv_setevent');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_setevent]
? end;
end;
{$ELSE}
function srv_setevent; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_message_handler: Pointer;
function srv_message_handler;
begin
? GetProcedureAddress(_srv_message_handler,'srv_message_handler');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_message_handler]
? end;
end;
{$ELSE}
function srv_message_handler; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_pre_handle: Pointer;
function srv_pre_handle;
begin
? GetProcedureAddress(_srv_pre_handle,'srv_pre_handle');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_pre_handle]
? end;
end;
{$ELSE}
function srv_pre_handle; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_post_handle: Pointer;
function srv_post_handle;
begin
? GetProcedureAddress(_srv_post_handle,'srv_post_handle');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_post_handle]
? end;
end;
{$ELSE}
function srv_post_handle; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_post_completion_queue: Pointer;
function srv_post_completion_queue;
begin
? GetProcedureAddress(_srv_post_completion_queue,'srv_post_completion_queue');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_post_completion_queue]
? end;
end;
{$ELSE}
function srv_post_completion_queue; external opendsdll;
{$ENDIF}

{$IFDEF DYNAMIC_LINK}
var
? _srv_IgnoreAnsiToOem: Pointer;
function srv_IgnoreAnsiToOem;
begin
? GetProcedureAddress(_srv_IgnoreAnsiToOem,'srv_IgnoreAnsiToOem');
? asm
??? mov esp,ebp
??? pop ebp
??? jmp [_srv_IgnoreAnsiToOem]
? end;
end;
{$ELSE}
function srv_IgnoreAnsiToOem; external opendsdll;
{$ENDIF}

{------------------------------------------------------------------------------}

function ODS_VERSION(): Integer;
begin
? Result := (SS_MAJOR_VERSION shl 24) or (SS_MINOR_VERSION shl 16);
end;

end.

?

?

Delphi5.0版本以上)中创建一DLL项目,加入上面的单元文件,创建一名为SQL_API.pas的新单元文件,内容如下:

unit SQL_API;

interface

uses Windows,OdsApi7;

const
? XP_SUCCEED??????? = 0;
? XP_ERROR????????? = 1;

? MAX_SERVER_ERROR? = 20000;
? XP_PARAM_ERROR??? = MAX_SERVER_ERROR + 1;

function xp_hello(srvproc: PSRV_PROC): RETCODE; cdecl;

implementation

uses SysUtils;

const
? MAXCOLNAME? = 25;
? MAXTXTNAME? = 32;
?
resourcestring
? xp_hello_Usage = 'usage: exec @Result = xp_hello @InputStr';

{------------------------------------------------------------------------------}

// send XP usage info to client?
procedure PrintSQLUsage(srvproc: PSRV_PROC; const szUsageMsg: string);
begin
? srv_sendmsg(srvproc,XP_PARAM_ERROR,nil,
??? DBUSMALLINT(1{__LINE__}),PChar(szUsageMsg),SRV_NULLTERM);
? srv_senddone(srvproc,(SRV_DONE_ERROR or SRV_DONE_MORE),0);
end;

// send XP error info to client
procedure PrintSQLError(srvproc: PSRV_PROC; const szErrorMsg: string);
begin
? srv_sendmsg(srvproc,XP_ERROR,PChar(szErrorMsg),0);
end;

{------------------------------------------------------------------------------}

function xp_hello(srvproc: PSRV_PROC): RETCODE;
var
? nParams,nParam: Integer;
? bType: BYTE;
? cbMaxLen,cbActualLen: Integer;
? Data: Pointer;
? fNull: BOOL;
?????
? DestStr: string;
? DestPtr,Source: PChar;
? DestLen: Integer;
begin
? Result := XP_ERROR;
? nParams := OdsApi7.srv_rpcparams(srvproc);
? // 检查参数数目
? if nParams < 2 then
? begin
??? PrintSQLUsage(srvproc,xp_hello_Usage);
??? Exit;
? end;

? // 取得参数
? for nParam := 1 to nParams do
? begin
??? if srv_paraminfo(srvproc,nParam,bType,cbMaxLen,cbActualLen,fNull) = FAIL then
??? begin
????? PrintSQLError(srvproc,Format(sGetParamError,[nParam]));
????? Exit;
??? end;
??? Data := srv_paramdata(srvproc,nParam);
??? case nParam of
????? 1:
??????? begin
????????? if srv_paramstatus(srvproc,nParam) <> SRV_PARAMRETURN then
????????? begin
??????????? PrintSQLError(srvproc,Format(sParamStatusError,[nParam]));
??????????? Exit;
????????? end;
??????? end;
????? 2:
??????? begin
????????? Source := Data;
??????? end;
??? end;
? end;?

? // 直接返回输入字符串
? DestStr := Source;
? DestLen := Length(DestStr);
? if DestLen > MaxLen then
? begin
??? PrintSQLError(srvproc,Format(sParamNotenough,[1,DestLen]));
??? Exit;
? end;
???
? // 调用返回
? GetMem(DestPtr,DestLen);
? try
??? System.Move(Pointer(DestStr)^,DestPtr^,DestLen);
??? srv_paramset(srvproc,DestPtr,DestLen);
??? srv_senddone(srvproc,(SRV_DONE_FINAL or SRV_DONE_MORE),0);
??? Result := XP_SUCCEED;
? finally
??? FreeMem(DestPtr,DestLen);
? end;
end;

exports
? xp_hello name 'xp_hello';

end.

?

?

示例xp_hello函数直接返回输入参数的内容,编译项目,生成DLL文件,OK,外部DLL文件开发完成。

?

3、接下来的工作是做什么呢?

?????? 先把编译好的DLL文件,我们把SqlDemo.DLL文件复制到SQLServer数据库的安装路径的bin目录下,然后回头看第一步的描述,引入DLL文件的扩展存储过程,然后编写SQL测试脚本验证其是否正常工作,引入及测试脚本如下:

/*?因为存储过程?sp_addextendedproc?只能在?master?库中运行,因此扩展存储过程只?*/

/*?能创建在?master?库中,而且必须以?sa?管理员登录后运行本脚本?????????????????*/

use ?master

go


if ? exists ( select ?name? from ?sysobjects? where ?name? = ? ' xp_hello ' ? and ?type? = ? ' X ' )

??
exec ?sp_dropextendedproc? ' xp_hello '

go


exec ?sp_addextendedproc?N ' xp_hello ' ,?N ' Algorism.dll '

go


-- 测试

declare

??
@Result ? int ,

??
@dest ? char ( 255 ),

??
@source ? varchar ( 255 )


select ? @dest = '' ,? @source ? = ? ' 测试数据 '

exec ? @Result ? = ?xp_hello? @dest ?output,? @source ?

if ? @Result ? = ? 0

??
select ? @dest ? as ?dest

-- ?此时,@dest的值变为?'测试数据'

?

?

到此,我们完成了一个扩展存储过程示例,下一篇介绍利用扩展存储过程实现加密。

上面本想对Delphi单元文件进行语法亮,但很遗憾,没有对Delphi的语法加亮功能,看来Delphi真的要没落了 :(

?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读