
这篇文章将会以实例形式一步步的来说明如何开发一个简单橡敬的自动化服务器
新建一个普通的应用程序 将工程保存为AutoSrv bpr 在主窗体上放一个Edit控件指拍 并保存为MainForm pas 在这里我们打算给这个程序加上对窗口标题 窗体颜色 和Edit控件文本的自动化控制(当然这实现的功能很少 但对于讲解如何开发自动化服务器程序足够了) 在主窗口中加入如下代码:(注意:请自行将这些函数和过程的声明加入TForm 的public区)function TForm GetCaption: stringbeginresult := Self Captionend
procedure TForm SetCaption(ACaption: string)beginSelf Caption := ACaptionend
procedure TForm SetColor(AColor: TColor)beginSelf Color := AColorend
procedure TForm SetEditText(AText: string)beginSelf Edit Text := ATextend然后我们来给这个程序加上自动化的功能 点击New Items按钮 在d出的New Items窗口中点击ActiveX选项卡 选择Automation Object点击OK按钮 在d出的Automation Object Wizard窗口中CoClass Name一项中输入MyAutoSrv Delphi就会自动生成一个AutoSrv_TLB pas文件(类库)和实现类库接口类的单元 将这个新的单元保存为AutoSrvClass pas.
现在这个程序已经成为一个自动化服务器了 我们再来为其加上自动化的接口函数:( )点击View >Type Libray菜单 在Type Library Editor选择IMyAutoSrv接口 点击New Property 选择其属性为Read|Write 并把其命名为Caption Type设定为BSTR ( )点击New Method 将其命名为SetColor 点击右边的Parameters选项卡 点击ADD为新添的接口函数添加一个参数 将参数名设为AColor 参数Type设为OLE_COLOR ( )再次点击New Method 将其命名为SetEditText 以上面的方法为其添加一个参数 将参数名设为AText 参数Type设为BSTR
最后添加上接口函数的实现代码就OK了:在AutoSrvClass pas的Uses部分添加上MainForm 并将其代码改为如下代码 unit AutoSrvClass
{$WARN SYMBOL_PLATFORM OFF}
interface
usesComObj ActiveX AutoSrv_TLB StdVcl MainForm
typeTMyAutoSrv = class(TAutoObject IMyAutoSrv)protectedfunction Get_Caption: WideStringsafecallprocedure Set_Caption(const Value: WideString)safecallprocedure SetColor(AColor: OLE_COLOR)safecallprocedure SetEditText(const AText: WideString)safecall
end
implementation
uses ComServ
function TMyAutoSrv Get_Caption: WideStringbeginResult := Form GetCaptionend
procedure TMyAutoSrv Set_Caption(const Value: WideString)beginForm SetCaption(Value)end
procedure TMyAutoSrv SetColor(AColor: OLE_COLOR)beginForm SetColor(AColor)end
procedure TMyAutoSrv SetEditText(const AText: WideString)beginForm SetEditText(AText)end
initializationTAutoObjectFactory Create(ComServer TMyAutoSrv Class_MyAutoSrv ciMultiInstance tmApartment)end 运行这个程序一次 将会自动注册为自动化服务器 可以在注册表中的HKEY_CLASSES_ROOT主键下面找到其相关的注册信息
上面演示了如何开发一个自动化服务器 在这里我们将调用它 新建一个程序 添加一个Button 在其VAR区声明一个Variant变量: AutoSrv: variant再在Button 中添加如下代码 procedure TForm Button Click(Sender: TObject)beginAutoSrv := CreateOleObject( AutoSrv MyAutoSrv ){这个字符串就是自动化服务器的工程名加上CoClass Name}Self Caption := AutoSrv CaptionAutoSrv Caption := HEHE AutoSrv SetColor(CLRed)AutoSrv SetEditText( HAHA )end其中的CreateOleObject函数将会返回一个IDispatch类型的接口 正是IDispatch接口让我们的程序可以对自动化服务器接口的调用进行后期连接 比如我们在上面添加一句AutoSrv Hello 程序也能被编释通过 但在执行时就会出错 使用Variant在执行效率上会比直接使用接口声明要慢一些 运行并点击按钮 可以看到自动化服务程序被加载 并按我们的代码设置了窗体色和EDIT 中的字串 呵呵 是不是很简单啊?
lishixinzhi/Article/program/Delphi/201311/24993
procedure TFrmTriggerDemo FormShow(Sender: TObject)
begin
DmEmployee EmployeeTable Open
DmEmployee SalaryHistoryTable Open
end
procedure TDmEmployee EmployeeTableAfterPost(DataSet: TDataSet)
begin
{ 一个雇员的薪水变化将触发薪水调整历史记录的变化
因此 如果SalaryHistory打开的话 就需要更新显示 }
with SalaryHistoryTable do if Active then Refresh
end
存储过程编程
存储过程也是SQL服务器上的一段程序 它接收输入参数 在服务器端执行 并将结果返回客户端 存储过程是必须在客户应用程序中显式调用的
对于数据库表中大量记录的统计和函数计算 存储过程是很有用 这样可哪闷以将重复性计算任务转换到服务器 提高数据库应用的性能
Delphi中有两个部件能 *** 作远程数据库服务器上的存储过程 TQuery和TStoredProc
TQuery的存储过程编程
CSDEMO中演示用TQuery调用存储过程的窗体是TFrmQueryProc
TFrmQueryProc中有两个TDBGrid 部件 DBGrid 显示EmployeeTable中的数据 DBGrid 显示Project表中的数据 使用存储过程的TQuery部件名为EmployeeProjectsQuery 它的作用是建立Employee 表和Project 表的连接 以实现当DBGrid 中记录改变时 DBGrid 中的数据作相应的改变 具体的连接任务是由服务器上的存储过程Get_Emp_Proj完成 下面是Get_Emp_Proj的程序
PROCEDURE Get_Emp_Proj
BEGIN
FOR SELECT proj_id
FROM employee_project
WHERE emp_no = :emp_no
INTO :proj_id
DO
SUSPEND
END
EMP_NO INPUT SMALLINT
PROJ_ID OUTPUT CHAR( )
该过程带两个参数
EMP_NO是输入参数 类型是SMALLINT
PROJ_ID是输出参数 类型是CHAR( )
相应地 EmployeeProjectsQuery的主要属性如下
表 EmployeeProjectsQuery部件主要属性的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━
属 性 属 性 值
──────────────────────────
DatabaseName EmployeeDemoDB
Params EMP_No(输入参数 Smallint类型)
SQL Select * from
Get_Emp_Proj(册缓槐 EMP_NO)
━━━━━━━━━━━━━━━━━━━━━━━━━━
TQuery部件是在州友SQL语句中直接调用存储过程
下面是客户端的程序
procedure TFrmQueryProc FormShow(Sender: TObject)
begin
DmEmployee EmployeeTable Open
EmployeeSource Enabled := True
with EmployeeProjectsQuery do if not Active then Prepare
end
用Prepare显式地准备SQL语句 虽非必须 但可以优化SQL的执行
procedure TFrmQueryProc EmployeeDataChange(Sender: TObjectField: TField)
begin
mployeeProjectsQuery Close
EmployeeProjectsQuery Params[ ] AsInteger :=
DmEmployee EmployeeTableEmp_No Value
EmployeeProjectsQuery Open
WriteMsg( Employee + DmEmployee EmployeeTableEmp_No AsString +
is assigned to + IntToStr(EmployeeProjectsQuery RecordCount) +
project(s) )
end
该事件处理过程与EmployeeSource的OnDataChange属性相联 用于当EmployeeTable数据记录变化时 修正存储过程的输入参数 并执行SQL语句
TStoredProc部件的存储过程编程
TStoredProc Delphi 专门用来使用服务器存储过程的部件 CSDEMO 中演示用TStoredProc调用存储过程的窗体是TFrmExecPr
在程序运行中 当按下ShipOrder按钮 要求对ORED_STA_TUS等字段的内容作修改以维护数据库的一致性 字段内容的修改任务由服务器上的存储过程SHIP_ORDER完成 SHIP_ORDE的程序如下
PROCEDURE SHIP_ORDER
DECLARE VARIABLE ord_stat CHAR( )
DECLARE VARIABLE hold_stat CHAR( )
DECLARE VARIABLE cust_no INTEGER
DECLARE VARIABLE any_po CHAR( )
BEGIN
SELECT s order_status c on_hold c cust_no
FROM sales s customer c
WHERE po_number = :po_num
AND s cust_no = c cust_no
INTO :ord_stat :hold_stat :cust_no
IF (ord_stat = shipped ) THEN
BEGIN
EXCEPTION order_already_shipped
SUSPEND
END
ELSE IF (hold_stat = * ) THEN
BEGIN
EXCEPTION customer_on_hold
SUSPEND
END
FOR SELECT po_number
FROM sales
WHERE cust_no = :cust_no
AND order_status = shipped
AND paid = n
AND ship_date <NOW
INTO :any_po
DO
BEGIN
EXCEPTION customer_check
UPDATE customer
SET on_hold = *
WHERE cust_no = :cust_no
SUSPEND
END
UPDATE sales
SET order_status = shipped ship_date = NOW
WHERE po_number = :po_num
SUSPEND
END
Parameters:
PO_NUM INPUT CHAR( )
该过程只带有一个输入参数 PO_NUM 类型是CHAR( )
在客户端使用该过程的TStoreProc部件是ShipOrderProc 其主要属性如下表
表 ShipOrderProc部件主要属性的取值
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
属性名 属 性 值
────────────────────────────
DatabaseName EmployeeDemoDB
ParamBindMode pbByName
Params PO_NUM(输入参数 String类型)
StoredProcName SHIP_ORDER
━━━━━━━━━━━━━━━━━━━━━━━━━━━━
lishixinzhi/Article/program/Delphi/201311/25127
TSoredProc的关键属性
⑴ DatabaseName属性
DatabaseName属性描述要访问的数据库的名字 该属性可以为
● 已定义的BDE别名
● 本地型数据库的目录
● Local InterBase服务器的目录路径和文件名
● TDatabase定义的应用程序别名
在改变DatabaseName之前要使用Close方法将Dataset部件置为非活跃状态
⑵ StoredProcName属性
StoredProcName属性表示服务器上的存储过程名 Oracle服务器允许多个具有相同名字的存储过程 因此要设置Overload属性来描述执行在Oracle服务器上的存储过程名
⑶ Overload属性
Oracle服务器允许Oracle软件包中存储过程的重载 就是说具有相同名字的不同过程 设置Overload属性用来描告巧述执行在Oracle服务器上的存储过程 如果Overload值为零 则假定没有重载 如果Overload为 则Delphi执行具有同名的第一个存储过程 如果值为 则执行第二个存储过程
好渗⑷ Params属性
Params属性包含传给存储过程的参数
关键方法
⑴ ParamByName方法
袜袜键 声明 function ParamByName(const Value: String) TParam
ParamByName方法返回Params属性中具有名为Value的元素值 一般用该方法在动态查询中给参数赋值
⑵ Prepare方法
PrePare方法准备要执行的存储过程 这允许服务器载入存储过程 否则准备处理异常
⑶ ExecProc方法
ExecProc方法执行服务器上的存储过程
⑷ Open方法
Open方法打开DataSet部件 并将其置于浏览状态 这相当于将Active属性置为True 对于TStoredProc如果存储过程返回一个结果集 则使用Open执行存储过程 如果存储过程返回单行 早使用ExecProc执行存储过程
TStoreProc使用方法
建立一个StoredProc部件
为数据库服务器上的存储过程建立一个TStoredProc部件的步骤如下
⑴ 从Component Palette的Data Access页选择TStoredProc部件放在数据模块上
⑵ 将TStoredProc部件的DatabaseName属性设置为存储过程所在的数据库名
DatabaseName必须是BDE别名
⑶ 将TStoredProc部件的StoredProcName属性设为所用的存储过程名 或者从下拉式
列表框中选择
⑷ 在TStoredProc部件的Params属性中描述输入参数 可以使用参数编辑器来设置输
入参数 参数编辑器也可让用户察看存储过程返回给应用程序的值
设置存储过程的输入参数 察看输出结果参数
许多存储过程需要给它们传入一系列的输入参数 以确定处理什么和怎样处理 在Params属性中描述这些参数 所描述的输入参数的顺序是很重要的 它由服务器上的存储过程来确定 在设计时 最容易和最安全的方法是激活TStoredProc参数编辑器 编辑输入参数 参数编辑器以正确的次序列出输入参数 让你给它们赋值
要激活TStoredProc的参数编辑器
① 选择TStoredProc部件
② 按鼠标右键激活加速菜单(Speed Menu)
③ 选择Define Parameters
参数名列表框显示过程的所有输入 输出和结果参数 有关输入 输出参数的信息从服务器中获得 对于某些服务器而方 参数信息是不可访问的 如Sybase 在这种情况下 列表框是空的 因此必须自己按过程要求的顺序增加输入输出参数
参数类型复选框中描述所选的参数是输入 输出 还是结果参数 如果服务器支持参数可以既是输入又是输出 如果在列表框中增添参数 就必须设置参数类型
数据类型复选框 列出列表框中所选参数的数据类型 如果给列表框真善美参数 必须设置数据类型
在值编辑框中给输入参数赋值
如果服务器不传递存储过程信息给Delphi 则可以用Add按钮给存储过程增添参数 Delete按钮则是将增添的参数删除 Clear按钮将清除列表框中所有参数
设置完参数后 选择OK按钮
在运行时建立参数和参数值
在运行时建立参数 可直接访问Params属性 Params属性是参数字符串的数组 例如 下列代码将编辑框的文本赋给数组的第一个字串
StaredProc Params[ ] Asstring := Edit Text
也能够用ParamsByName方法通过名字访问参数
StoredProc ParamsByName( Company ) Asstring := Edit Text
准备和执行存储过程
要使用存储过程还必须准备并执行它 可以有两种方式准备一个存储过程
● 在设计时 通过选择参数编辑器的OK按钮
● 在运行时 通过调用TStoredProc的Prepare方法
例如 下面的代码准备存储过程的执行
StoredProc Prepare
要执行准备好的存储过程 调用TStroedProc部件的ExecProc方法 下列代码演示了准备和执行存储过程
StoredProc Params[ ] Asstring := Edit Text
StoredProc prepare
StoredProc ExecProc
当你执行一个存储过程 它返回输出参数或结果集 有两种可能的返回类型 单个返回 如单值或值集 和一群结果集 返回很多值
访问输出参数和结果集
存储过程在输出参数数组中返回值 如果服务器支持返回值可以是单个结果或者结果集
在运行时访问存储过程的输出参数 可以索引Params属性或者用ParamByName方法访问这些值 下列表达式都用输出参数设置了编辑框的值
Edit Text := StoredProc Params[ ] AsString
Edit Text := StoredProc ParamsByName( Contact ) AsString
如果存储过程返回结果集 则用标准数据相关控制访问和显示值会更有用
在某些服务器上如Sybase 存储过程能象查询语句那样返回结果集 应用程序可以使用数据相关控制一显示这些存储过程的输出
用数据相关控制显示存储过程返回结果的方法如下
① 将DataSource部件放在数据模块上
② 将DataSource部件的DataSet属性设置为接收数据的TStoredProc部件的名字
③ 将数据相关控制的DataSource属性设为DataSource部件的名字
这样 当用于TStoredProc部件和Active属性为True时 数据相关控制就能显示从存储过程返回的结果
返回目录 DELPHI基础教程
编辑推荐
Java程序设计培训视频教程
J EE高级框架实战培训视频教程
Visual C++音频/视频技术开发与实战
Oracle索引技术
ORACLE G数据库开发优化指南
Java程序性能优化 让你的Java程序更快 更稳定
C嵌入式编程设计模式
Android游戏开发实践指南
lishixinzhi/Article/program/Delphi/201311/25132
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)