Delphi中如何调用存储过程

合集下载

delphi adostoredproc1用法

delphi adostoredproc1用法

delphi adostoredproc1用法Delphi ADOStoredProc1 是 Delphi 编程语言中的一个组件,用于执行存储过程的相关操作。

它是 ADO(ActiveX Data Objects)技术的一部分,允许开发人员通过 Delphi IDE(集成开发环境)来操作数据库。

使用 Delphi ADOStoredProc1 组件可以方便地连接和操作各种数据库,例如Microsoft SQL Server、Oracle、MySQL 等。

它提供了一些属性和方法,使开发人员能够执行存储过程以及与数据库进行交互。

首先,在 Delphi 中使用该组件前,需要在项目中引入 ADO 组件库。

然后,可以在设计时或运行时创建和配置 ADOStoredProc1 对象。

创建对象后,我们可以通过设置属性来定义要执行的存储过程的名称、连接字符串、参数等信息。

为了使用Delphi ADOStoredProc1 组件执行存储过程,我们可以使用以下步骤:1. 确保已正确设置连接字符串。

连接字符串确定了要连接的数据库。

可以通过设置 Connected 属性为 True 来建立与数据库的连接。

2. 设置存储过程的名称。

通过设置 StoredProcName 属性来指定要执行的存储过程的名称。

3. 配置参数。

根据存储过程的定义,可能需要提供输入参数、输出参数或返回值。

可以使用 Parameters 属性来访问和配置参数集合。

4. 调用存储过程。

可以通过调用ExecProc 方法来执行存储过程。

在调用之前,确保已设置好参数的值。

执行存储过程后,可以通过检查参数的值来获取返回的结果。

如果存储过程有输出参数或返回值,可以使用 Parameters 属性访问它们。

Delphi ADOStoredProc1 组件提供了很多其他的属性和方法,可以用于执行与存储过程相关的操作,如事务处理、错误处理等。

通过熟悉和掌握这些功能,开发人员可以更灵活、高效地使用 Delphi 进行数据库开发,并实现各种功能需求。

delphi中调用oracle的存储过程

delphi中调用oracle的存储过程

【delphi+oracle报表解决方案(一)】delphi中调用oracle的存储过程(分带返回游标,不返回值两种)关键字: delphi ,oracle存储过程,游标,返回数据集,报表注:delphi 6+ oracle 8.1.6一.创建包与包体1.附:建表aaclass为下面作测试用create table aaclass(CID V ARCHAR2(50), CNAME V ARCHAR2(50), pnumber NUMBER(10,0) );INSERT INTO aaclass values('c1', 'cn1', 10 ) ;INSERT INTO aaclass values('c2', 'cn2', 40 ) ;INSERT INTO aaclass values('c1', 'cn3', 30 ) ;commit;2.建包:CREATE OR REPLACE PACKAGE PKG_JCCTEST1 AStype rc_class is ref cursor;--求p1,p2的和与差,返回的多个值通过游标返回procedure GetSubAndSum2(p1 number,p2 number ,ResultCursor out rc_class);--查询满足条件的数据集,返回数据集通过游标返回procedure GetClass2(a in number,ResultCursor out rc_class ) ;--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,p_pnumber number) ;end PKG_JCCTEST1;3.建包体CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1procedure GetSubAndSum2(p1 number,p2 number ,ResultCursor out rc_class)ISBEGINopen ResultCursor forselect p1-p2 as "sum", p1+p2 as "sub" from dual;END ;procedure GetClass2(a in number,ResultCursor out rc_class ) isbeginopen ResultCursor forselect aaclass.* from aaclass where pnumber >a;end ;procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,p_pnumber number)begininsert into aaclass values(p_cid,p_cname,p_pnumber) ;-- commit;end ;二.在delphi中利用AdoDataSet调用上述第一个存储过程1.利用AdoConnection1连接数据库(驱动为oracle Provider for OLE DB),**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=12.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。

delphi中调用oracle的存储过程

delphi中调用oracle的存储过程

【delphi+oracle报表解决方案(一)】delphi中调用oracle的存储过程(分带返回游标,不返回值两种)关键字: delphi ,oracle存储过程,游标,返回数据集,报表注:delphi 6+ oracle 8.1.6一.创建包与包体1.附:建表aaclass为下面作测试用create table aaclass(CID V ARCHAR2(50), CNAME V ARCHAR2(50), pnumber NUMBER(10,0) );INSERT INTO aaclass values('c1', 'cn1', 10 ) ;INSERT INTO aaclass values('c2', 'cn2', 40 ) ;INSERT INTO aaclass values('c1', 'cn3', 30 ) ;commit;2.建包:CREATE OR REPLACE PACKAGE PKG_JCCTEST1 AStype rc_class is ref cursor;--求p1,p2的和与差,返回的多个值通过游标返回procedure GetSubAndSum2(p1 number,p2 number ,ResultCursor out rc_class);--查询满足条件的数据集,返回数据集通过游标返回procedure GetClass2(a in number,ResultCursor out rc_class ) ;--往表中插一条记录,不返回结果集时,本人用AdoQuery调用(adodataset好象要求必须返回结果集)procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,p_pnumber number) ;end PKG_JCCTEST1;3.建包体CREATE OR REPLACE PACKAGE BODY PKG_JCCTEST1procedure GetSubAndSum2(p1 number,p2 number ,ResultCursor out rc_class)ISBEGINopen ResultCursor forselect p1-p2 as "sum", p1+p2 as "sub" from dual;END ;procedure GetClass2(a in number,ResultCursor out rc_class ) isbeginopen ResultCursor forselect aaclass.* from aaclass where pnumber >a;end ;procedure InsertClass( p_cid varchar2 ,p_cname varchar2 ,p_pnumber number)begininsert into aaclass values(p_cid,p_cname,p_pnumber) ;-- commit;end ;二.在delphi中利用AdoDataSet调用上述第一个存储过程1.利用AdoConnection1连接数据库(驱动为oracle Provider for OLE DB),**并在连接字符串中加入这一节: PLSQLRSet=1; 如下所示:Provider=OraOLEDB.Oracle.1;Password=KXD;Persist Security Info=True;User ID=KXD;Data Source=TEST3;PLSQLRSet=12.在窗体上加AdoDataSet1 指明连接为上述AdoConnection1,下面可以放一个按钮,单击按钮就能调用第一步中创建的包过程,并返回数据集。

Delphi 中的dll 封装和调用对象方法

Delphi 中的dll 封装和调用对象方法

Delphi 中的dll 封装和调用对象方法2011-01-28 22:18动态链接库是一种特殊格式的二进制数据文件,后缀名为.dll。

它可以在程序运行时调用,并不需要进行重新编译,又由于它是完全独立的一个功能模块,使得其重用性非常好。

将dll载入内存后,dll中的功能接口可以被系统中任何正在运行的应用程序所使用。

具有节省空间,升级容易和高重用性等优点。

很多delphi的教材资料上讲到dll,大多都是将用dll来封装一些函数或者过程。

但有时我们想把某个问题当成一个对象来处理,使程序模块化、组件化,方便团队开发、维护和更新。

这时我们就需要用到dll封装和调用对象的技术,然而delphi在封装对象方面有一定的技术难度,资料也比较少,使得很多程序员认为delphi的dll不支持对象封装。

下面简单分享一下我学习dll对象封装和调用的一些心得,希望能对这方面有需求的程序员一些帮助。

首先让我们认识一点,调用dll的程序只能使用与dll中对象动态绑定的方法,理解这一点是实现Dll封装和使用对象的关键。

理解了这一点,我们就会想怎样才能实现与dll中对象的动态绑定呢?Delphi的接口技术为我们提供了一个好的选择,我们可以通过接口类去动态的获取dll中的对象。

下面我用一个简单的demo来说明如何实现。

我建立了这样一个工程组,如下图按如下几步进行:1、先定义一个接口单元IDemo,代码如下:unit IDemo;interfacetypeIMax = interface (IInterface)function Max(num1, num2 : Integer) : Integer;end;implementationend.建立我们需要封装的对象单元UnitMax.pas,注意看TMax继承自哪些父类,代码如下:unit UnitMax;interfaceusesIDemo;typeTMax = class(TInterfacedObject, IMax)function Max( num1, num2 : Integer ) : Integer;end;implementationfunction TMax.Max(num1: Integer; num2: Integer) : Integer;beginResult := 0;if num1 > num2 thenResult := num1elseResult := num2;end;end.3、再在dll单元,输入如下代码:library ProjectDll;usesShareMem,SysUtils,Classes,IDemo in 'IDemo.pas',UnitMax in 'UnitMax.pas',{$R *.res}function MaxObj : IMax;beginResult := TMax.Create;end;exportsMaxObj,end.这样一个提供对象接口的dll就完成了,点击build编译就行了。

delphi+sqlserver jpg-bmp图片存取

delphi+sqlserver jpg-bmp图片存取

procedure Tf_st.N1Click(Sender: TObject); 图片存储vara:ansistring;f:ansistring;bitfile:tbitmap;jpgfile:tjpegimage;beginif xs_state='1' thenexit;openpicturedialog1.Execute;a:=openpicturedialog1.FileName;if a <>'' thentryimage1.Picture.LoadFromFile(a);if (image1.Picture.Graphic.Height>340) or (image1.Picture.Graphic.Width>240) then beginshowmessage('图片尺寸太大,请调整到340×240');image1.Picture.Graphic:=nil;exit;end;///jpg->>.bmpif (lowercase(extractfileext(a))='.jpg') or (lowercase(extractfileext(a))='.jpeg') then beginimage1.Picture.Graphic:=nil;GroupBox3.Caption:='正在进行JPG到BMP格式转化';f:=a+'.bmp' ;bitfile:=tbitmap.Create();jpgfile:=tjpegimage.create();tryjpgfile.LoadFromFile(a);bitfile.Width:= jpgfile.Width;bitfile.Height:=jpgfile.Height;bitfile.Assign(jpgfile);bitfile.SaveToFile(f);finallybitfile.Free;jpgfile.Free;end;GroupBox3.Caption:=' 转化成功';image1.Picture.LoadFromFile(f);end;///exceptshowmessage('装载图片出错!');end;end;……..if image1.Picture.Graphic=nil thens:=s+')'elses:=s+',:b)' ;with datamodule1.ADOQuery3 dobeginclose;sql.Clear;sql.Add(s);if not (image1.Picture.Graphic=nil) thenParameters.ParamByName('b').Assign(image1.Picture.Graphic);tryexecsql;exceptshowmessage('添加信息失败,请再试试');exit;end;end;image1.Picture.Graphic:=nil;f_main.ADOQuery4.Active :=false;f_main.ADOQuery4.Active:=true;showmessage('信息添加成功!');。

delphi如何调用sql存储过程,并获取结果

delphi如何调用sql存储过程,并获取结果
ADOStoredProc1.ExecProc;
showmessage(inttostr(ADOStoredProc1.Parameters.ParamByName('@mycount').value));
end;
在TADOStoredProc当中由使用Refresh而自动将所对应的存储过程的参数填充给TADOStoredProc本身的时候,默认会把所有的OutPut参数配置为pdInputOutput,所以在执行的时候ADO自身就会提示你需要对相应的参数值进行初始化,比如本例当中可以将参数@GetTotalSale赋一个初始值,然后程序就可以调试通过了。
adostoredproc1.ExecProc;
edit1.Text :=adostoredproc1.Parameters[0].Value;
最简单的存储过程
数据库端
CREATE PROCEDURE aaa
@www varchar(10) //参数
AS
select * from employees where pusercode=@www
ADOStoredProc1.ExecProc; //
{ 假设你已经有一个存贮过程在SQL服务器中,
那么你和程序就需要一个adoconnection设置数据库连接,
adostoredproc 的
connection连接adoconnection后
GO
如何提取参数
procedure TFrm_worker_info.Button1Click(Sender: TObject);
var outcount:integer;
begin

delphi tunistoredproc 返回值参数

delphi tunistoredproc 返回值参数

Delphi TUniStoredProc 返回值参数1. 介绍Delphi是一种用于创建Windows应用程序的集成开发环境(IDE),而TUniStoredProc是Delphi中的一个组件,用于执行存储过程。

在使用TUniStoredProc时,我们可以设置返回值参数来获取存储过程的返回结果。

本文将详细介绍如何在Delphi中使用TUniStoredProc组件来处理返回值参数,并提供一些示例代码和实际应用场景。

2. TUniStoredProc 组件TUniStoredProc组件是Delphi中的一个数据库访问组件,它允许开发人员执行存储过程并获取结果。

要使用TUniStoredProc组件,需要首先创建一个数据库连接并设置相关属性。

以下是一些常用的TUniStoredProc属性:•Connection:指定数据库连接对象。

•StoredProcName:指定要执行的存储过程名称。

•Params:定义输入和输出参数。

•Prepare:准备要执行的存储过程。

•ExecProc:执行存储过程。

•ParamByName:通过参数名称获取参数对象。

3. 设置返回值参数要设置返回值参数,需要在Params集合中添加一个新的参数对象,并将其Direction属性设置为pdReturnValue。

这样就可以将该参数作为存储过程的返回结果。

以下是通过代码设置返回值参数的示例:procedure TForm1.Button1Click(Sender: TObject);beginUniStoredProc1.Params.Clear;UniStoredProc1.Params.CreateParam(ftInteger, 'ReturnValue', ptResult);UniStoredProc1.Prepare;UniStoredProc1.ExecProc;ShowMessage(IntToStr(UniStoredProc1.ParamByName('ReturnValue').AsInteger)); end;在上面的示例中,我们首先清除了Params集合中的所有参数,然后创建了一个名为”ReturnValue”的整数参数,并将其Direction属性设置为ptResult。

delphi如何使用存储过程

delphi如何使用存储过程

如果有大量的数据在服务器与客户端之间传递,就会降低程序执行的速度,影响应用程序的性能。

针对这种情况,MS SQL Server 数据库和Delphi开发工具都提供了存储过程来解决这类问题。

存储过程是一段在服务器上执行的程序,它在服务器端对数据库记录进行处理,再把结果返回...一、概述Delphi + MS SQL Server是目前最为流行的管理信息系统开发环境和工具。

Delphi的强大数据库操作控件极大地减轻了开发人员的工作量,在这些控件中,最常用的有TQuery、TTable、TADOQuery、TADOTable、TADODataSete等,这些控件执行查询操作时有一个共同的特点,即将所有数据库记录从服务器取回客户端,再根据查询的条件进行筛选。

很明显,如果有大量的数据在服务器与客户端之间传递,就会降低程序执行的速度,影响应用程序的性能。

针对这种情况,MS SQL Server数据库和Delphi开发工具都提供了存储过程来解决这类问题。

存储过程是一段在服务器上执行的程序,它在服务器端对数据库记录进行处理,再把结果返回到客户端。

通过使用存储过程,一方面可以利用服务器强大的计算能力和速度,另一方面避免把大量的数据从服务器下载到客户端,减少网络上传输量,服务器只需将计算结果传给客户端,其效率之高是非常明显的。

二、创建存储过程在MS SQL Server上的存储过程可分为二类,一类是类似于select 查询,用于检索数据,检索到的数据能够以数据集的形式返回给客户端,如CREATE procedure proc1@dw char(20)asselect dwdm from cchdwdm where dw=@dw该存储过程有一个输入参数@dwdm,以数据集的形式返回结果。

另一类存储过程是通过输出参数返回信息或不返回信息,或只执行一个动作。

如:CREATE procedure proc2@m1 smallint,@m2 smallint@result int OUTPUTasselect @result=@m1*@m2该存储过程有二个输入参数@m1、@m2,还有一个输出参数@result。

多线程数据查询与存储在Delphi中的实现

多线程数据查询与存储在Delphi中的实现

多线程数据查询与存储在Delphi中的实现1、引言:随着数据的存储、修改及查询变得更加频繁优秀的数据库应用程序,应当充分考虑数据库访问的速度问题。

通常可以通过优化数据库、优化查询语句、分页查询等途径收到明显的效果。

但是,大家都会遇到这样的问题,在较短的时间里,对服务器端数据访问或操作过于频繁时,主程序的窗口会出现一个带有SQL符号的沙漏。

如果数据存储的量很大时,主程序会出现死机的情况,用户只好重新启动应用程序。

这在实际中是不允许的,因为这样会丢失重要的数据,那么有没有好的解决方法呢?分析造成这种现象的原因,主要有2个方面。

第一,对数据库的访问处理放在了主程序的前端处理;第二,忽略了网络数据处理的并发性[1]。

在实际Delphi的编程应用中,由于Delphi的强大功能和支持多线程的面向对象编程技术,使得实现网络数据的并发存储及查询变得非常简单方便。

2、多线程技术在Delphi的编程中,可以很方便的使用多线程,可以在后台调用一个线程,直接对数据进行操作处理,而用户可以继续其他程序操作,不必关心该数据的处理。

使用多线程技术,可以达到数据存储与查询的并行操作,即可以使用一个线程进行数据存储,另一个线程进行数据的查询,2个线程操作互不影响。

这样大大地提高了程序的效率。

3、多线程的实现实现多线程的数据库同步访问的基本思想是:为每个数据操作(如TQuery组件)创建一个独占的数据库会话对象,然后各自进行数据库访问。

在Delphi数据库应用中,都有一个缺省的数据会话对象Tsession。

假如在进行一个线程存储时,用户可通过按钮或菜单发出查询命令,此时,可以不必终止正在执行的数据库的访问[3]。

下面的例子给出了同时进行的2个线程操作,一个是存储,另一个是查询。

这里的多线程同步查询、存储演示程序仅包括一个工程文件和一个单元文件,窗体中放置的组件有2个Session组件、2个Button组件。

3.1、查询线程类的实现方法procedureTThreadQuery.Execute;begintryFQuery.Open;{打开查询}exceptShowMessage(cFQueryErrorc);{线程异常}end;Terminate;end;constructorTThreadQuery.Create(Suspended:Boolean;Session:TSession); beginFQuery:=Tquery.create(nil);{動态产生}FDatabase.SessionName:=Session1.SessionName;FQuery.SessionName:=Database.SessionName;FQuery.DatabaseName:=Database.Data-baseName;dd(sql语句);inheritedCreate(True);FreeOnTerminate:=true;end;destructorTThreadQuery.Destroy;beginFdataBase.Free;Fquery.Free;end;3.2存储线程类的实现方法procedureTThreadSave.Execute;beginDatabase.StartTransaction;trySquery.ExecSQL;mi;exceptDatabase.Rollback;end;Terminate;end;procedureTForm1.BtnGoQueryClick(Sender:TOb2ject);beginTThreadQuery.Create(false,Session){点击查询按钮创建查询线程}end;procedureTForm1.BtnGoSaveClick(Sender:TOb2ject);beginTThreadSave.Create(false,Session){点击存储按钮创建存储线程}end;在上面这个例子中,我们构造2个TThread的子类,用于在后台执行数据库查询和存储。

finereport调用存储过程

finereport调用存储过程

finereport调用存储过程
Finereport是一款强大的报表工具,可以连接各种数据源,包括数据库。

如果需要在Finereport中执行存储过程,可以通过以下步骤实现:
1.创建数据源
在Finereport中创建连接数据库的数据源,并测试连接是否正确。

2.创建数据集
在数据集中选择数据源,并输入存储过程的名称。

如果需要传递参数,可以在“参数”项中添加。

然后点击“测试”按钮验证是否能成功执
行存储过程。

3.创建报表
在报表中添加数据集,可以在数据集中选择需要显示的字段。

然后运
行报表,即可看到执行存储过程后的结果。

以上三个步骤是Finereport调用存储过程的基本流程。

当然,如果需
要更加复杂的操作,可以使用Finereport提供的高级功能。

例如,如果需要在执行存储过程后根据返回结果进行不同的处理,可
以在数据集中编写Groovy脚本,并使用if语句等实现。

还可以在报表中添加自定义按钮,通过调用Groovy脚本实现更加复杂
的功能。

这些高级操作需要一定的编程经验和技能,但可以达到很高
的灵活性和定制化程度。

总之,Finereport是一款功能强大、易于使用的报表工具,可以连接各种数据源,并支持执行存储过程。

通过以上步骤,可以快速地实现在Finereport中显示存储过程的结果。

Delphi-调用存储过程的方法

Delphi-调用存储过程的方法

Delphi-调⽤存储过程的⽅法 Delphi控件⾥拉⼀个TADOStoredProc,配置好相关链系,具体的操作列⼦如下:1procedure TForm1.btnFirstClick(Sender: TObject);2begin34 sp1.Close;5 sp1.Parameters.Clear;6 sp1.ProcedureName:= 'Proc_SplitPage2';78 sp1.Parameters.CreateParameter('tblName',ftString,pdInput,20,fgUnassigned);9 sp1.Parameters.CreateParameter('strFields',ftString,pdInput,20,fgUnassigned);10 sp1.Parameters.CreateParameter('strOrders',ftString,pdInput,20,fgUnassigned);11 sp1.Parameters.CreateParameter('strOrderType',ftString,pdInput,20,fgUnassigned);12 sp1.Parameters.CreateParameter('PageSize',ftInteger,pdInput,4,fgUnassigned);13 sp1.Parameters.CreateParameter('PageIndex',ftString,pdInput,20,fgUnassigned);14 sp1.Parameters.CreateParameter('strWhere',ftString,pdInput,20,fgUnassigned);1516 // exec [Proc_SplitPage2] 'NewsInfo','*','ID','ASC',10,3,''17 sp1.Parameters[0].Value := 'NewsInfo';18 sp1.Parameters[1].Value := '*';19 sp1.Parameters[2].Value := 'ID';20 sp1.Parameters[3].Value := 'DESC';21 sp1.Parameters[4].Value := 10;22 sp1.Parameters[5].Value := 1;23 sp1.Parameters[6].Value := '';2425 sp1.ExecProc;26 sp1.Open;2728end;2930procedure TForm1.FormShow(Sender: TObject);31begin32 pageIndex := 1;33end;3435procedure TForm1.btnPreClick(Sender: TObject);36begin3738 sp1.Close;39 sp1.Parameters.Clear;40 sp1.ProcedureName:= 'Proc_SplitPage2';4142 sp1.Parameters.CreateParameter('tblName',ftString,pdInput,20,fgUnassigned);43 sp1.Parameters.CreateParameter('strFields',ftString,pdInput,20,fgUnassigned);44 sp1.Parameters.CreateParameter('strOrders',ftString,pdInput,20,fgUnassigned);45 sp1.Parameters.CreateParameter('strOrderType',ftString,pdInput,20,fgUnassigned);46 sp1.Parameters.CreateParameter('PageSize',ftString,pdInput,20,fgUnassigned);47 sp1.Parameters.CreateParameter('PageIndex',ftString,pdInput,20,fgUnassigned);48 sp1.Parameters.CreateParameter('strWhere',ftString,pdInput,20,fgUnassigned);4950 // exec [Proc_SplitPage] 'NewsInfo','*','ID','DESC','10','1',''51 sp1.Parameters[0].Value := 'NewsInfo';52 sp1.Parameters[1].Value := '*';53 sp1.Parameters[2].Value := 'ID';54 sp1.Parameters[3].Value := 'ASC';55 sp1.Parameters[4].Value := '10';56 pageIndex := pageIndex - 1;57 sp1.Parameters[5].Value := pageIndex;58 sp1.Parameters[6].Value := '';5960 sp1.ExecProc;61 sp1.Open;62end;6364procedure TForm1.btnNextClick(Sender: TObject);65begin6667 sp1.Close;68 sp1.Parameters.Clear;69 sp1.ProcedureName:= 'Proc_SplitPage2';70 sp1.Parameters.CreateParameter('tblName',ftString,pdInput,20,fgUnassigned);71 sp1.Parameters.CreateParameter('strFields',ftString,pdInput,20,fgUnassigned);72 sp1.Parameters.CreateParameter('strOrders',ftString,pdInput,20,fgUnassigned);73 sp1.Parameters.CreateParameter('strOrderType',ftString,pdInput,20,fgUnassigned);74 sp1.Parameters.CreateParameter('PageSize',ftString,pdInput,20,fgUnassigned);75 sp1.Parameters.CreateParameter('PageIndex',ftString,pdInput,20,fgUnassigned);76 sp1.Parameters.CreateParameter('strWhere',ftString,pdInput,20,fgUnassigned);7778 sp1.Parameters[0].Value := 'NewsInfo';79 sp1.Parameters[1].Value := '*';80 sp1.Parameters[2].Value := 'ID';81 sp1.Parameters[3].Value := 'ASC';82 sp1.Parameters[4].Value := '10';83 pageIndex := pageIndex + 1;84 sp1.Parameters[5].Value := pageIndex;85 sp1.Parameters[6].Value := '';8687 sp1.ExecProc;88 sp1.Open;89end;。

Delphi 文件操作

Delphi 文件操作

Delphi 文件操作var file_name:string;file_name:='c:\luther.gliethttp.txt';FileWrite(com.log_fd, PChar(file_name)^, length(file_name));文件是同一种类型元素的有序集合,是内存与外设之间传输数据的渠道。

文件的本质是一个数据流,所有的文件实际上是一串二进制序列。

文件管理包括:1、文件操作。

2、目录操作。

3、驱动器操作。

三部分。

1、常见文件操作函数和过程。

1.1、AssignFile过程作用:将一个外部文件的文件名与一个File类型的变量关联,并对变量进行初始化。

原型:procedure AssignFile(var F; FileName: String);F:一个File类型的变量,可以是任何数据类型。

FileName:外部文件的文件名。

1.2、FileExists函数作用:用于测试指定文件名的文件是否存在。

原型:function FileExists(const FileName: String): Boolean;FileName:文件名。

字符串类型。

注意:如果文件存在,返回True;否则,返回False。

1.3、Append过程作用:为在一个已经存在的文件末尾添加文本做好准备工作。

文件是只写方式打开的。

原型:procedure Append(var F: Text);F: 一个TextFile类型变量。

注意:这是一个对文本类型文件操作的过程。

其中变量F必须和外部文件关联。

如果F 没有与外部文件关联,将抛出异常。

如果F已经处于打开状态,则过程会关闭F并重新打开。

文件指针位置将被设置在文件末尾。

1.4、Reset过程作用:对于文本文件,Reset过程将以只读方式打开文件。

对于类型文件和无类型文件,Reset过程将以可读写方式打开文件。

原型:procedure Reset(var F [: File; RecSize: Word ] );F:File类型变量,可以是任何文件类型。

DELPHI数据控件TclientDataSet的详细说明

DELPHI数据控件TclientDataSet的详细说明

DELPHI数据控件TclientDataSet的详细说明与TTable、TQuery一样,TClientDataSet也是从TDataSet继承下来的,它通常用于多层体系结构的客户端。

TClientDataSet最大的特点是它不依赖于BDE(Borland Database Engine),但它需要一个动态链接库的支持,这个动态链接库叫DBCLIENT.DLL。

在客户端,也不需要用TDatabase构件,因为客户端并不直接连接数据库。

由于TClientDataSet是从TDataSet继承下来的,所以,它支持诸如编辑、搜索、浏览、纠错、过滤等功能。

由于TClientDataSet 在内存中建立了数据的本地副本,上述操作的执行速度很快。

也正是由于TClientDataSet并不直接连接数据库,因此,客户程序必须提供获取数据的机制。

在Delphi4中,TClientDataSet有三种途径获取数据:.从文件中存取数据。

.从本地的另一个数据集中获取数据。

.通过IProvider接口从远程数据库服务器获取数据。

在一个客户程序中,可以同时运用上述三种机制获取数据。

1、浏览和编辑数据和其他数据集构件一样,可以用标准的数据控件显示由TClientDataSet引入的数据集,当然,这需要借助于TDataSource 构件。

由于TClientDataSet是从TDataSet继承下来的,所以,凡是其他数据集构件支持的功能,TClientDataSet构件也大致具备。

不同的是,TClientDataSet能够在内存中建立数据的副本,因此,TClientDataSet比其他数据集构件增加了一些特殊的功能。

1.1、浏览数据可以用标准的数据控件显示由TClientDataSet引入的数据集。

在运行期,可以调用诸如First、GotoKey、Last、Next和Prior等函数来浏览数据。

TClientDataSet也支持书签功能,可以用书签来标记某条记录,以后就可以方便地找到这条记录。

Delphi调用存储过程在出版社MIS的开发应用

Delphi调用存储过程在出版社MIS的开发应用

Delphi调用存储过程在出版社MIS的开发应用
罗骏;黄东
【期刊名称】《计算机技术与发展》
【年(卷),期】2005(015)003
【摘要】为了处理好开发数据库应用系统采用存储过程的时机,介绍了Delphi调用存储过程在图书创利结算模块中的技术实现.通过使用两层结构,实现客户端/服务器模式,能够实现局域网上多用户对数据库的同时访问.给出了在后台数据库的存储过程的设计,提供了开发C/S结构中的应用经验.通过模块的运行加强了对各图书策划人的绩效考核,提高了图书选题的质量.
【总页数】3页(P95-97)
【作者】罗骏;黄东
【作者单位】东南大学,自动控制系,江苏,南京,210096;东南大学,自动控制系,江苏,南京,210096
【正文语种】中文
【中图分类】TP311.5
【相关文献】
1.在VB中实现存储过程的调用 [J], 韦立梅;李郁林;张淑荣
中调用数据库存储过程方法的研究与实现 [J], 王红;陈功平
3.C#调用存储过程实现身份验证 [J], 修长虹;李杰夫;辛艳
4.VFP调用ORACLE存储过程数据库接口程序 [J], 杨波;施松杉;赵娟
5.Java调用数据库存储过程的研究与实现 [J], 李焕玲
因版权原因,仅展示原文概要,查看原文内容请购买。

Delphi的内存操作函数

Delphi的内存操作函数

Delphi的内存操作函数Delphi 的内存操作函数马上能想到的函数有:GetMemAllocMemReallocMemFreeMemGetMemoryReallocMemoryFreeMemoryNewDisposeNewStrDisposeStrStrNewStrAllocStrDisposeGlobalAllocPtrGlobalFreePtrWideStrAllocAnsiStrAllocStrDisposeMoveMoveMemoryCopyMemoryZeroMemoryFillMemoryFillCharStrBufSize给字符指针(PChar、PWideChar、PAnsiChar)分配内存, 最佳选择是: StrAlloc.StrAlloc 虽然最终也是调用了GetMem, 但StrAlloc 会在指针前面添加Delphi 需要的4 个管理字节(记录长度).StrAlloc 分配的内存, 用StrDispose 释放, 用StrBufSize 获取大小.用FreeMem 释放可以吗? 这样会少释放4 个字节.这种类型的指针一般用于API 函数的参数, 譬如获取窗口标题:varp: PChar;beginp := StrAlloc(256);GetWindowText(Handle, p, StrBufSize(p));ShowMessage(p); {Form1}StrDispose(p);end;StrAlloc 根据不同的参数(PWideChar、PAnsiChar)分别重载调用了WideStrAlloc、AnsiStrAlloc, 所以我们也可以直接使用这两个函数(这也需要用StrDispose 释放), 不过使用它们的必要性不大; 用StrAlloc 指定好参数类型即可.给字符指针分配内存其他方法也挺方便, 譬如://获取 WINDOWS 所在目录varbuf: array[0..MAX_PATH] of Char;beginGetWindowsDirectory(buf, Length(buf));ShowMessage(buf); {C:\\WINDOWS}end;数组的内存不是我们自己申请的, 系统会自动释放; 记住: 只要是手动申请的内存一定要手动释放.我们给字符指针申请内存主要是为了在API 中接受数据, 如果我们要直接赋给常量值, 系统会自动分配内存的, 譬如:varp: PChar;beginp := '万一的 Delphi 博客';ShowMessage(p); {万一的 Delphi 博客}end;当然我们也可以用这种办法申请内存, 就是笨了点, 譬如://获取系统目录varp: PChar;beginp := PChar(StringOfChar(Char(0), 256)); {反复一个空字符 256 次成一个字符串, 然后转为 PChar}GetSystemDirectory(p, StrBufSize(p));ShowMessage(p); {C:\\WINDOWS\\system32}end;如果在API 函数需要的字符指针是为了输入, 当然也不需要申请内存, 譬如://设置窗口标题varp: PChar;beginp := '窗口新标题';SetWindowText(Handle, p);end;//也可以直接给常量beginMessageBox(Handle, '提示信息', '标题', MB_OK);end;//如果是给字符串的变量或常量, 则需要转换一下varstr: string;beginstr := '万一的 Delphi 博客';TextOut(Canvas.Handle, 10, 10, PChar(str), Length(str));{在窗体上输出文字, 此代码不能在 OnCreate 事件中}end;跑题了...到现在已用到了StrAlloc、StrDispose、WideStrAlloc、AnsiStrAlloc、StrBufSize 几个函数.还有NewStr、DisposeStr、StrNew、StrDispose 也貌似有点关系.先说NewStr 和DisposeStr(它们是一对);NewStr 是根据AnsiString 再新建一个PAnsiString, 不过这是为兼容而存在的, Delphi 已不提倡使用了.不再提倡使用的函数都缀以deprecated 标识, 并在代码提示中用灰色显示.其实用@ 即可获取字符串指针, 当然根本用不着它们.还有个StrNew; StrNew 可以再制一个相同的字符指针, 譬如:varp1,p2: PChar;beginp1 := 'Delphi';p2 := StrNew(p1);ShowMessageFmt('%s, %s', [p1, p2]); {Delphi, Delphi}p1 := '2009';ShowMessageFmt('%s, %s', [p1, p2]); {2009, Delphi}StrDispose(p2); {释放自己申请的}end;不过StrNew 存在的意义也不大, 我们可以更简单地完成上面的操作:varp1,p2: PChar;beginp1 := 'Delphi';p2 := p1;ShowMessageFmt('%s, %s', [p1, p2]); {Delphi, Delphi}p1 := '2009';ShowMessageFmt('%s, %s', [p1, p2]); {2009, Delphi}end;说来说去, 好像只有StrAlloc 是我们值得我们记忆的?还有一对非常重要的相关函数: GlobalAllocPtr、GlobalFreePtr; 它们的功能是上面这些都不可替代的!GlobalAllocPtr 和GlobalFreePtr 是对系统函数: GlobalAlloc、GlobalFree 的简化, 之所以说它们重要, 只是因为它们可以跨进程操作; 不过GlobalAllocPtr 是给无类型指针(Pointer)分配内存, 当然就不仅仅用于字符指针了. 还是到后面专题再做例子吧.静态数组, 在声明时就分配好内存了, 譬如:vararr1: array[0..255] of Char;arr2: array[0..255] of Integer;beginShowMessageFmt('数组大小分别是: %d、%d', [SizeOf(arr1), SizeOf(arr2)]);{数组大小分别是: 512、1024}end;对静态数组指针, 虽然在声明之处并没有分配内存, 但这个指针应该分配多少内存是有定数的.这种情况, 我们应该用New 和Dispose 来分配与释放内存. 譬如:typeTArr1 = array[0..255] of Char;TArr2 = array[0..255] of Integer;vararr1: ^TArr1;arr2: ^TArr2;beginNew(arr1);New(arr2);arr1^ := '万一的 Delphi 博客';ShowMessageFmt('%s%s', [arr1^[0], arr1^[1]]); {万一}// ShowMessageFmt('%s%s', [arr1[0], arr1[1]]); {这样也可以} arr2[Low(arr2^)] := Low(Integer); {第一个元素赋最小值} arr2[High(arr2^)] := MaxInt; {第一个元素赋最大值}ShowMessageFmt('%d, %d', [arr2[0], arr2[255]]);{-2147483648, 2147483647}Dispose(arr1);Dispose(arr2);end;//变通一下, 再做一遍这个例子:typeTArr1 = array[0..255] of Char;TArr2 = array[0..255] of Integer;PArr1 = ^TArr1;PArr2 = ^TArr2;vararr1: PArr1;arr2: PArr2;beginNew(arr1);New(arr2);arr1^ := '万一的 Delphi 博客';ShowMessageFmt('%s%s', [arr1[0], arr1[1]]);arr2[Low(arr2^)] := Low(Integer);arr2[High(arr2^)] := MaxInt;ShowMessageFmt('%d, %d', [arr2[0], arr2[255]]);{-2147483648, 2147483647}Dispose(arr1);Dispose(arr2);end;给已知大小的指针分配内存应该用New, 上面的例子是关于静态数组指针的, 后面要提到的结构体(记录)的指针也是如此.New 的本质也函数调用GetMem, 但不需要我们指定大小了.但这对动态数组就不合适了, 不过给动态数组分配内存SetLength 应该足够了, 譬如:vararr: array of Integer;beginSetLength(arr, 3);arr[0] := Random(100);arr[1] := Random(100);arr[2] := Random(100);ShowMessageFmt('%d,%d,%d', [arr[0],arr[1],arr[2]]); {0,3,86} end;那怎么给动态数组的指针分配内存呢? 其实动态数组变量本身就是个指针, 就不要绕来绕去再给它弄指针了.不过有一个理念还是满重要的, 那就是我们可以把一个无类型指针转换为动态数组类型, 譬如:TArr = array of Integer;varp: Pointer;beginGetMem(p, 3 * SizeOf(Integer)); {分配能容纳 3 个 Integer 的空间}{这和 3 个元素的 TArr 的大小是一样的, 但使用时需要进行类型转换}TArr(p)[0] := Random(100);TArr(p)[1] := Random(100);TArr(p)[2] := Random(100);ShowMessageFmt('%d,%d,%d', [TArr(p)[0], TArr(p)[1],TArr(p)[2]]); {0,3,86}FreeMem(p);end;这里用到了GetMem 和FreeMem, 对分配无类型指针这是比较常用的; 对其他类型的指针它可以, 但不见得是最好的方案, 譬如: //获取窗口标题(显然不如用前面说过的 StrAlloc 更好)varp: Pointer;beginGetMem(p, 256);GetWindowText(Handle, p, 256);ShowMessage(PChar(p)); {Form1}FreeMem(p);end;应该提倡用GetMemory 和FreeMemory 代替GetMem、FreeMem, 譬如:varp: Pointer;p := GetMemory(256);GetWindowText(Handle, p, 256);ShowMessage(PChar(p)); {Form1}FreeMemory(p);end;先总结下:New 是给已知大小的指针分配内存;GetMem 主要是给无类型指针分配内存;尽量使用GetMemory 来代替GetMem.还有个AllocMem 和它们又有什么区别呢?AllocMem 分配内存后会同时初始化(为空), GetMem 则不会, 先验证下:varp1,p2: Pointer;beginp1 := AllocMem(256);ShowMessage(PChar(p1)); {这里会显示为空}FreeMemory(p1);p2 := GetMemory(256);ShowMessage(PChar(p2)); {这里会显示一些垃圾数据, 内容取决与在分配以前该地址的内容}FreeMemory(p2);end;关于FreeMemory 与FreeMem 的区别:1、FreeMemory 会检查是否为nil 再FreeMem, 这有点类似: Free 与Destroy;2、FreeMem 还有个默认参数可以指定要释放的内存大小, 不指定就全部释放(没必要只释放一部分吧);3、New 对应的Dispose 也可以用FreeMem 或FreeMemory 代替.尽量使用FreeMemory 来释放GetMem、GetMemory、AllocMem、ReallocMem、ReallocMemory 分配的内存.ReallocMem、ReallocMemory 是在已分配的内存的基础上重新分配内存, 它俩差不多ReallocMemory 比ReallocMem 多一个nil 判断, 尽量使用ReallocMemory 吧. 譬如:typeTArr = array[0..MaxListSize] of Char;PArr = ^TArr;vararr: PArr;i: Integer;beginarr := GetMemory(5);for i := 0to4do arr[i] := Chr(65+i);ShowMessage(PChar(arr)); {ABCDE}arr := ReallocMemory(arr, 26);ShowMessage(PChar(arr)); {ABCDE}for i := 0to25do arr[i] := Chr(65+i);ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ} end;注意上面这个例子中TArr 类型, 它被定义成一个足够大的数组; 这种数组留出了足够的可能性, 但一般不会全部用到.我们一般只使用这种数组的指针, 否则一初始化将会内存不足而当机.即便是使用其指针, 也不能用New 一次行初始化; 应该用GetMem、GetMemory、AllocMem、ReallocMem、ReallocMemory 等用多少申请多少.需要注意的是, 重新分配内存也可能是越分越少; 如果越分越大应该可以保证以前数据的存在.这在VCL 中TList 类用到的理念.如果你在心里上接受不了那么大一个数组(其实没事, 一个指针才多大? 我们只使用其指针), 也可以这样:TArr = array[0..0] of Char;PArr = ^TArr;vararr: PArr;i: Integer;beginarr := GetMemory(5);for i := 0to4do arr[i] := Chr(65+i);ShowMessage(PChar(arr)); {ABCDE}arr := ReallocMemory(arr, 26);ShowMessage(PChar(arr)); {ABCDE}for i := 0to25do arr[i] := Chr(65+i);ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ} end;这好像又让人费解, 只有一个元素的数组能干什么?应该这样理解: 仅仅这一个元素就足够指示数据的起始点和数据元素的大小和规律了.另外的SysGetMem、SysFreeMem、SysAllocMem、SysReallocMem 四个函数, 应该是上面这些函数的底层实现, 在使用Delphi 默认内存管理器的情况下, 我们还是不要直接使用它们.使用结构或结构数组, 一般是不需要主动分配内存的, 譬如:varpts: TPoint;beginpts.X := 1;pts.Y := 2;ShowMessageFmt('%d,%d', [pts.X, pts.Y]); {1,2}end;//结构数组:Arr: array[0..2] of TPoint;i: Integer;beginfor i := 0to Length(Arr) - 1dobeginArr[i].X := i;Arr[i].Y := Trunc(Sqr(i));end;ShowMessageFmt('%d,%d', [Arr[High(Arr)].X,Arr[High(Arr)].Y]); {2,4}end;但在很多时候, 一些参数是结构指针; 特别是在接受数据时, 一般需要手动分配内存. 如果只使用一个单结构指针, 用New 分配内存是最合适的, 譬如:varp: PPoint; {这是点结构 TPoint 的指针, 系统早定义好的}beginNew(p);// p^.X := 1; p^.Y := 2; {或者写成下面这样}p.X := 1; p.Y := 2;ShowMessageFmt('%d,%d', [p.X, p.Y]);Dispose(p);end;更多时候, 我们需要给一个结构指针分配更多容量; GetMem 可以很容易地完成这个任务, 关键是如何访问. 譬如:varp: PPoint;beginp := GetMemory(4 * SizeOf(TPoint)); {分配能容纳 4 个 TPoint结构的内存}{下面的代码访问了第一个结构, 其他 3 个怎么访问呢?}p.X := 1; p.Y := 11;ShowMessageFmt('%d,%d', [p.X, p.Y]); {1,11}FreeMemory(p);end;//访问给结构指针分配的其他元素:varp: PPoint;buf: array[0..255] of Char;beginp := GetMemory(4 * SizeOf(TPoint)); {分配能容纳 4 个 TPoint 结构的内存}p.X := 1; p.Y := 11;Inc(p); {指向第二个结构}p.X := 2; p.Y := 22;Inc(p); {指向第三个结构}p.X := 3; p.Y := 33;Inc(p); {指向第四个结构}p.X := 4; p.Y := 44;{既然用了 Inc, 那么在释放或使用前, 必须把指针退回到起始点!} Dec(p, 3);{读出看看; 注意这里的 wvsprintf 也是格式化函数, 有时它更方便} wvsprintf(buf, '%d,%d; %d,%d; %d,%d; %d,%d', PChar(p)); ShowMessage(buf); {1,11; 2,22; 3,33; 4,44}FreeMemory(p);end;如上的操作简直太残忍了, 幸亏数据少; 其实这种情况应该用数组, 这里提供一种更巧妙的办法- 转换(为数组类型):varp: PPoint;i: Integer;buf: array[0..255] of Char;typeArrPoint = array of TPoint; {用于转换的自定义类型}beginp := GetMemory(4 * SizeOf(TPoint));for i := 0to3dobeginArrPoint(p)[i].X := i;ArrPoint(p)[i].Y := i * i;end;wvsprintf(buf, '%d,%d; %d,%d; %d,%d; %d,%d', PChar(p)); ShowMessage(buf); {0,0; 1,1; 2,4; 3,9}FreeMemory(p);end;FillMemory、ZeroMemory 一目了然的两个函数, 但其实它们都是调用了FillChar;清空不过就是填充空字符(#0: 编号为0 的字符), 说来说去是一回事.为了下面的测试, 先写一个以十六进制方式查看内存的函数:function GetMemBytes(var X; size: Integer): string;varpb: PByte;i: Integer;beginpb := PByte(X);for i := 0to size - 1dobeginResult := Result + IntToHex(pb^, 2) + #32;Inc(pb);end;end; {GetMemBytes end}//测试:varp1: PAnsiChar;p2: PWideChar;s1: AnsiString;s2: UnicodeString;beginp1 := 'ABCD';p2 := 'ABCD';s1 := 'ABCD';s2 := 'ABCD';ShowMessage(GetMemBytes(p1,4)); {41 42 43 44}ShowMessage(GetMemBytes(p2,8)); {41 00 42 00 43 00 44 00} ShowMessage(GetMemBytes(s1,4)); {41 42 43 44} ShowMessage(GetMemBytes(s2,8)); {41 00 42 00 43 00 44 00} end;测试FillMemory、ZeroMemory、FillChar 三个填充函数:constnum = 10;varp: PChar;beginp := StrAlloc(num);ShowMessage(GetMemBytes(p, num)); {从结果看出StrAlloc 没有初始化内存}FillMemory(p, num, Byte('A'));ShowMessage(GetMemBytes(p, num)); {41 41 41 41 41 41 41 41 41 41}ZeroMemory(p, num);ShowMessage(GetMemBytes(p, num)); {00 00 00 00 00 00 00 00 00 00}FillChar(p^, num, 'B');ShowMessage(GetMemBytes(p, num)); {42 42 42 42 42 42 42 42 42 42}StrDispose(p);end;此时, 我想到一个问题:GetMem 和GetMemory 没有初始化内存; AllocMem 会初始化内存为空, 那么ReallocMem、ReallocMemory 会不会初始化内存?测试一下(结果是没有初始化):{测试1}varp: Pointer;beginp := GetMemory(3);ShowMessage(GetMemBytes(p, 3));ReallocMem(p, 10);ShowMessage(GetMemBytes(p, 10)); {没有初始化}FreeMemory(p);end;{测试2}varp: Pointer;beginp := AllocMem(3);ShowMessage(GetMemBytes(p, 3));ReallocMem(p, 10);ShowMessage(GetMemBytes(p, 10)); {没有初始化}FreeMemory(p);end;另外: FillMemory、ZeroMemory 的操作对象是指针, 而FillChar 的操作对象则是实体.MoveMemory、CopyMemory 的功能是一模一样的, 都是复制内存, 都是调用Move 过程;MoveMemory、CopyMemory 操作指针; Move 操作实体.还要注意, 它们的参数位置不一样!举例:{例1}varbuf1,buf2: array[0..9] of AnsiChar; beginbuf1 := '0123456789';buf2 := 'abcdefghij';Move(buf2[2], buf1[4], 5);ShowMessage(buf1); {0123cdefg9}ShowMessage(buf2); {abcdefghij} end;{例2}varbuf1,buf2: array[0..9] of AnsiChar; beginbuf1 := '0123456789';buf2 := 'abcdefghij';CopyMemory(@buf2[2], @buf1[4], 5);ShowMessage(buf1); {0123456789}ShowMessage(buf2); {ab45678hij} end;{例3}vars1,s2: TStringStream; {两个字符串流} begins1 := TStringStream.Create;s2 := TStringStream.Create;{向第一个字符串流写入}s1.WriteString('万一的 Delphi 博客');ShowMessage(s1.DataString); {万一的 Delphi 博客}{设置第二个字符串流的大小}s2.SetSize(6);{从第一个流复制到第二个流}CopyMemory(s2.Memory, s1.Memory, s2.Size);ShowMessage(s2.DataString); {万一的}s1.Free;s2.Free;end;这里仅仅是为了测试, 如果真的使用TMemoryStream、TStringStream 等流类, 它们自身提供的复制操作更方便.Delphi 为我们提供了三个方便的函数:GlobalAllocPtr {简化自 API 的 GlobalAlloc}GlobalReAllocPtr {简化自 API 的 GlobalReAlloc}GlobalFreePtr {简化自 API 的 GlobalFree}读写本程序以外的数据时可以使用它们, 很方便, 譬如:p := GlobalAllocPtr(0, Len); {分配}p := GlobalReAllocPtr(p, Len, 0); {重分配}GlobalFreePtr(p); {释放}注意GlobalAllocPtr 的第一个参数和GlobalReAllocPtr 的最后一个参数, 上面给的都是0;这两个参数的意义是一样的, 规范一点应该写成GMEM_FIXED (表示分配固定内存), 常用的参数还有:GMEM_MOVEABLE {分配可移动内存}GMEM_ZEROINIT {同时清空内存}GHND {分配可移动内存同时清空}GPTR {分配固定内存同时清空}参数还有很多, 和相应的API 函数的参数是一致的.下面的例子并没有使用进程以外的对象, 可以把Memo1.Handle 换做外部的其他文本容器(譬如记事本)试一试:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Memo1: TMemo;Button1: TButton;Button2: TButton;procedure FormCreate(Sender: TObject);procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);end;varForm1: TForm1;implementation。

Linq调用存储过程

Linq调用存储过程

Linq 调用存储过程普通存储过程首先在查询分析器运行下面的代码来创建一个存储过程:然后打开IDE的服务器资源管理器,之前我们从表中拖动表到dbml设计视图,这次我们从存储过程中找到刚才创建的存储过程,然后拖动到设计视图。

在方法面板中可以看到已经创建了一个sp_singleresultset的方法,如下图:然后打开Northwind.designer.cs,可以找到下面的代码:我们可以发现,IDE为这个存储过程单独生成了返回结果集的实体定义,你可能会觉得很奇怪,IDE怎么知道这个存储过程将会返回哪些数据那?其实,在把存储过程拖拽入dbml设计视图的时候,IDE就执行了类似下面的命令:这样就可以直接获取存储过程返回的元数据而无须执行存储过程。

其实我们存储过程返回的就是顾客表的数据,如果你觉得为存储过程单独设置结果集实体有些浪费的话可以在存储过程的属性窗口中调整返回类型从“自动生成的类型”到Customer,不过以后你只能通过删除方法面板中的存储过程,然后重新添加来还原到“自动生成的类型”。

下面,我们可以写如下的Linq to object代码进行查询:在这里确实是Linq to object的,因为查询句法不会被整句翻译成SQL,而是从存储过程的返回对象中再去对对象进行查询。

SQL代码如下:带参数的存储过程创建如下存储过程:使用同样的方法生成存储过程方法,然后使用下面的代码进行测试:结果输出了“01”。

说明ID为“”的顾客数为0,而ID为“ALFKI”的顾客数为1。

存储过程的输出参数被封装成了ref参数,对于C#语法来说非常合情合理。

SQL代码如下:带返回值的存储过程再来创建第三个存储过程:生成方法后,可以通过下面的代码进行测试:运行后程序输出“100101”多结果集的存储过程再来创建一个多结果集的存储过程:找到生成的存储过程方法:由于现在的VS2008会把多结果集存储过程识别为单结果集存储过程(只认识第一个结果集),我们只能对存储过程方法多小动手术,修改为:然后使用下面的代码测试:使用存储过程新增数据存储过程除了可以直接调用之外,还可以用于实体的增删改操作。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
我将ADOConnection1更名为ADOCnn,将ADOStoredProc1更名为ADOSP
主要代码:
procedure TmainForm.FormCreate(Sender: TObject);
begin
ADOSP.Connection:=ADOCnn;//将ADOSP连接到ADOCnn
end;
procedure TmainForm.WriteClick(Sender: TObject);
begin
//注意,调用存储过程时,要按参数出现的顺序.
//调用插入数据的存储过程
with adoSP do
begin
Close;
ProcedureName:='InsertKevin';
2、当然用到存储过程,必须先在SQL SERVER 2000中建好必要的存储过程。我建立了4个存储过程,功能分别是插入数据,修改数据,删除数据,查找数据。一般MIS系统中用到也就这些。(1)、插入数据存储过程:
CREATE PROCEDURE [InsertKevin]
(@test nvarchar(50),@test2 nvarchar(50)) AS
insert into kevin(test,test2)
values
(@test,@test2)
GO
(2)、修改数据存储过程:
CREATE PROCEDURE [UpdateKevin]
(@id int,@test nvarchar(50),@test2 nvarchar(50))
ExecPro数据的存储过程
with adoSP do
begin
CLose;
ProcedureName:='FindKevin';
Parameters.Clear;
Parameters.CreateParameter('ID',ftInteger,pdInput,1,3);
估计有很多朋友用delphi写过与SQL Server 2000数据结合的一些MIS系统,对于大量的数据保存,及数据更新.常常考虑到用存储过程来实现...今天我写了一个简单的例子,希望能给一些朋友一点帮助....
1、当然,我们要在SQL SERVER 2000中建好我们的数据库及数据表。我这里用的数据库是reg_nis,其中我新建了一张表叫kevin(ID Int not null,test nvarchar(50),test2 nvarchar(50))其中有三个字段,ID是自动增长,增长率为1。
// ExecProc;//在执行命令的存储过程中用ExecProc
Open; //在查询的存储过程时,用OPEN;也可用
end;
// edit1.Text :=adoSP.Parameters[0].Value;
end;
Parameters.Clear;
Parameters.CreateParameter('test',ftString,pdInput,50,'abc');
Parameters.CreateParameter('test2',ftString,pdInput,50,'fff');
Parameters.CreateParameter('test',ftString,pdInput,50,'eee');
Parameters.CreateParameter('test2',ftString,pdInput,50,'ddd');
ExecProc;
end;
//调用删除数据的存储过程
with adoSP do
begin
CLose;
ProcedureName:='DeleteKevin';
Parameters.Clear;
Parameters.CreateParameter('ID',ftInteger,pdInput,1,15);
AS
update kevin set test=@test,test2=@test2 where [ID]=@id
GO
(3)删除数据存储过程:
CREATE PROCEDURE [DeleteKevin]
(@id int)
AS
delete from kevin where [ID]=@id
GO
(4)、查找数据存储过程
CREATE PROCEDURE [FindKevin]
(@id int)
AS
select * from kevin where [ID]=@id
GO
3、接下来,就在Delphi7中新建一个工程了。用一个ADOConnection1控件连接到数据库Reg_Nis。再放一个ADOStoredProc1控件,执行存储过程的。
ExecProc;
end;
//调用修改数据的存储过程
with adoSP do
begin
CLose;
ProcedureName:='UpdateKevin';
Parameters.Clear;
Parameters.CreateParameter('ID',ftInteger,pdInput,1,15);
相关文档
最新文档