第8章存储过程本章学习要点l学习StoredProc和ADOStoredProc组件l掌握存储过程的创建、执行、更新和删除方法l学习使用存储过程l掌握调用执行无参数存储过程l掌握调用执行带参数存储过程lMicrosoft存储过程(StoredProcedure)是数据库中较高级的应用,它其实就是数据库服务器端的一段程序,是在数据库服务器端执行的语句和可选控制流语句的预编译集合,使用存储过程可以提高应用程序的数据处理能力。根据这些程序的功能可以将它们分为两类。一类是类似于SELECT查询,用于检索数据,检索到的数据能够以数据集的形式返回给用户;另一类类似于INSERT或DELETE查询,它不返回数据,只是执行一个动作。在存储过程和应用程序进行交互的时候,需要用一些参数来传递信息。这些参数可以分为输入参数、输出参数、输入/输出参数以及状态参数等。存储过程执行查询时,可变参数的值和插入记录时字段的值等需要应用程序传递给存储过程,这种参数叫输入参数。存储过程将查询的结果传递给应用程序,这在存储过程中叫输出参数。有时候,在执行存储过程前需要由应用程序将参数的值传递给存储过程,在执行完毕后再由存储过程传递给应用程序,这种称为输入/输出参数。另外,存储过程在执行完毕后,通过状态参数将错误信息传递给应用程序。本章首先介绍存储过程组件,接着创建和编辑存储过程,以及带参数的存储过程,最后给出了在Delphi中调用存储过程的具体实现方法和使用实例。Microsoft8.1存储过程组件在Delphi中,可以使用StoredProc组件和Query组件来访问和操纵服务器上的存储过程。使用哪一种组件是由存储过程的实现,数据结果的返回以及使用的数据库服务器共同决定的。StoredProc组件和Query组件都是数据集组件,从DataSet派生而来。但是,用这两种组件来访问存储过程时是有很多差别的。StoredProc组件适合于执行那些不需要返回数据,并且通过输出参数来返回信息的存储过程。StoredProc组件的Params属性用于管理这些参数,同时,StoredProc组件的GetResults方法可以显式地申请返回结果。Delphi中除了通过StoredProc和Query组件完成存储过程的动态维护以外,还可以使用ADO组件面板上的ADOStoredProc组件在客户程序中调用服务器中的存储过程。下面介绍以下StoredProc组件的重要属性和方法。Microsoft8.1.1StoredProc组件的重要属性和方法StoredProc组件属于数据集组件,所有数据集组件共有的属性它都具有。另外,它还有自己特有的属性,如表8-1所示。属性含义Overload决定在Oracle服务器上执行哪一种存储过程的重载ParamBindMode决定组件在服务器上执行存储过程时,参数列表中各参数的先后顺序ParamCount指明了组件在执行存储过程中使用参数的数目Params储存存储过程中输入和输出的参数Prepared标志执行存储过程的准备工作是否已完成StmtHandle为了在存储过程中直接调用BDE的API函数StoredProcName表示服务器上的存储过程名表8-1StoredProc组件特有属性Microsoft下面详细介绍StoredProc组件的几个重要属性。Overload属性:用来说明在一个Oracle服务器上将执行哪一种重载的存储过程。一个Oracle重载的存储过程是和其他的存储过程同名的。Oracle服务器通过给每个过程一个特有的数码标识来区别重载的存储过程。应用程序可以通过Overload属性来指明数码标识。默认时,Overload属性值为0,表明没有存储过程的重载。如果Overload属性值为1,BDE将执行第一种重载过程,如果Overload属性值为2,BDE将执行第二种,依次类推。需要注意的是,Oracle的重载过程是同名的,但它们的参数列表却各不相同,应用程序必须确保提供的参数列表与重载过程相符。Params属性:用来储存存储过程中输入和输出的参数的。其属性值是一个参数值的数组。在运行时可以通过访问Params属性值来动态地设置参数名、参数值和数据类型。在执行了存储过程之后,应用程序也可以通过访问Params属性值来获得服务器返回给过程的输出参数。ParamCount属性:用来指明Params属性中存储参数的数目。Microsoft下面举例说明Params属性的使用:withStoredProc1do//设置输入参数fori:=0toParamCount-1doif(Params[1].paramtype=ptinput)or(Params[1].paramtype=ptoutput)thenParams[1].asstring:='';StoredProcName属性:用来指明服务器调用的存储过程名。如果StoredProcName属性中指明的存储过程名与服务器上存在的存储过程名不相符,则当应用程序为存储过程做准备时,会产生一个异常事件。StoredProc具有所有数据集组件的方法,它特有的方法如表8-2所示。方法功能CopyParams复制一个存储过程中的参数到另一个参数列表中Create新建一个存储过程控件DescriptionsAvailable标志服务器是否可以返回存储过程的参数Destory撤消一个存储过程ExecProc执行服务器上的存储过程GetResults取得一个Sybase存储过程的返回参数ParamByName根据参数名访问参数信息Prepare为执行存储过程进行准备UnPrepare释放在先前准备操作时分配给存储过程的资源Microsoft下面详细介绍StoredProc组件的特有方法中最重要的几个。Create方法:在应用程序中通过调用Create方法来初始化一个已声明的存储过程。Create方法调用它派生的Create构造器,为该存储过程建立一个新的空参数列表,并将其参数、服务器和记录缓冲区都清空。ExecProc方法:用来执行服务器上的存储过程。在调用ExecProc方法前,必须先进行下述操作:l在Params属性中给出所有存储过程需要的参数。在设计阶段,可以通过使用ParametersEditor对话框给出参数,见图8-1所示。在运行时,应用程序需要直接访问Params属性。l调用Prepare方法联系各参数。图8-1Parameters编辑框图8-2在ObjectInspector中设置ProcedureName属性Microsoft当ExecProc将控制权重新交给应用程序时,如果存储过程返回了输出参数,它们将被存储在Params属性中。通过Params属性的参数列表索引,或者通过调用ParamByName方法,应用程序可以访问这些输出参数。如果应用程序只是对存储过程的返回结果感兴趣,那么调用StoredProc的Open方法或设置它的Active属性值为True即可。GetResults方法:调用GetResults方法使一个Sybase存储过程返回给客户。对其它服务器,存储过程的结果会自动返回给客户;而对于Sybase存储过程,直到记录指针指向数据集的末尾它才会返回结果。GetResults方法正是使记录指针指向数据集的末尾。ParamByName方法:其基本格式如下:FunctionParamByName(constValue:string):Tparam;调用ParamByName方法会根据参数名获取相应的参数信息。Value就是希望获取信息的参数的名字。通过调用ParamByName方法可以在运行时设置输入参数,或者用来获取输出参数的值。Microsoft下面举例说明ParamByName方法的使用:StoredProc1.Open;WhilenotStoredProc1.EOFdobeginStoredProc1.Next;{执行存储过程}end;StoredProc1.GetResults;Edit1.Text:=StoredProc1.ParamByName(‘Output’).AsString;Prepare方法:调用Prepare方法是用来在调用ExecProc方法开始存储过程之前建立参数间的联系的。通过调用Prepare方法准备好存储过程的参数,初始化BDE,让BDE和远程的数据库服务器为存储过程分配资源并执行一些优化操作。在执行存储过程前调用Prepare方法会提高应用程序的执行效率。在第一次执行查询前,Delphi会自动完成准备工作,并在完成存储过程后释放占用的资源。Microsoft8.1.2怎样使用StoredProc组件来实现存储过程下面介绍如何使用StoredProc组件来执行指定的存储过程。在应用程序中如何使用一个存储过程是由存储过程的实现、数据结果的返回、使用的数据库系统或它们共同决定的。如果想用StoredProc组件来访问数据库服务器上的存储过程,一般需要先初始化一个StoredProc组件,然后再执行存储过程。1.初始化StoredProc组件可以通过以下几个步骤来初始化一个StoredProc组件。l在窗体或者数据模块上添加一个StoredProc组件;l设置StoredProc组件的DatabaseName属性来连接数据库;l通过StoredProc组件的StoredProcName属性来指定一个想使用的存储过程;设置StoredProc组件的Params属性来设置存储过程的参数;Microsoft(1)连接数据库连接数据库是通过设置StoredProc组件的DatabaseName属性来实现的。当然可以用StoredProc组件来直接连接数据库。如果用StoredProc组件来连接数据库时,它的DatabaseName属性可设为数据库的BDE别名,当数据库是Paradox或dBase等数据库时,也可以是数据表所在的目录;如果用Database组件来连接数据库的话,StoredProc控件的DatabaseName属性可设置为应用程序专用的别名。如果在应用程序的设计阶段无法与数据库连接的话,可以通过忽略DatabaseName属性而提供存储过程名、输入输出参数和结果参数来创建一个存储过程控件。如果通过这种忽略DatabaseName属性的方法在设计阶段创建一个存储过程控件,即该存储过程控件没有与服务器上的存储过程相连,就必须通过StoredProcParametersEditor对话框设置附加的输入参数信息,例如参数名和数据类型等等。Microsoft(2)指定存储过程如果连接了数据库,那么在StoredProc组件的StoredProcName属性右侧的下拉列表里就会显示该数据库中所有的存储过程,用户可以从中选择。在数据库应用程序运行的时候,可以设置通过StoredProc组件的StoredProcName属性值来执行不同的存储过程。(3)设置参数双击Params属性框激活StoredProc组件的Parameters编辑框来检查存储过程的输入和输出参数。如果上一步中没有设置StoredProcName属性值或设置的存储过程名在DatabaseName属性指定的服务器上不存在,那么当激活StoredProc组件的Parameters编辑框时,它是空的。2.执行一个存储过程(1)准备工作在执行一个存储过程前,需要做一些准备工作,即要通知数据库服务器。如果是在设计阶段,可以通过Parameters编辑框给出参数做准备;如果在程序的运行阶段,可以调用StoredProc组件的Prepare方法,如:StoredProc1.Prepare;如果应用程序在运行阶段改变了存储过程的参数,例如使用了Oracle的重载过程,就需要重新准备存储过程,即必须重新调用StoredProc组件的Prepare方法。Microsoft(2)执行存储过程在完成了准备工作后,就可以调用StoredProc组件的ExecProc方法来执行指定的存储过程。以下的程