实施别的系统时遇到一个问题,就是在SQL Server中中使用新建服务器连接方式连接到数据库Oracle时查询和写入某个表时出错,后来想到用一个外挂的程序来操作,可需要触发条件,轮询的话涉及到及时性和网络负荷问题.到网上一搜索,发现可以在SQL Server的存储过程或触发器中调用COM组件,这就比较好解决了.
首先建立一个COM服务器,只在里面写一个测试方法:Hello:
1
function
TCotest.Hello(
const
Value: WideString): WideString;
2 begin
3 Result: = ' 您输入的是: ' + Value;
4 end ;
2 begin
3 Result: = ' 您输入的是: ' + Value;
4 end ;
可以在IDE中注册这个服务器,或者在初始化代码后加入自动注册的代码:
1
initialization
2 TComponentFactory.Create(ComServer, TCotest,
3 Class_Cotest, ciMultiInstance, tmApartment);
4 ComServer.UpdateRegistry(true);
5 end .
2 TComponentFactory.Create(ComServer, TCotest,
3 Class_Cotest, ciMultiInstance, tmApartment);
4 ComServer.UpdateRegistry(true);
5 end .
从D2007开始需要手工加入:
ComServer.UpdateRegistry(true);
否则COM服务器不能自动注册(当然可以手工注册) .
好了,可以先写个客户端测试一下,放个TDCOMConnection组件,设定好服务器的名称,OK,可以正常激活这个COM组件.
用代码来调用测试一下吧:
1
var
2 v:Variant;
3 s: string ;
4 begin
5 v: = CreateOleObject( ' Project4.Cotest ' );
6 s: = v.Hello( ' Garfield ' );
7 ShowMessage(s);
8 v : = Unassigned;
9 end ;
2 v:Variant;
3 s: string ;
4 begin
5 v: = CreateOleObject( ' Project4.Cotest ' );
6 s: = v.Hello( ' Garfield ' );
7 ShowMessage(s);
8 v : = Unassigned;
9 end ;
注意:要引用ComObj单元.
程序可以正常执行并返回结果,说明COM组件运行正常.
好了,让我们来到关键的SQL Server中,可以在查询分析器中或建立一个储存过程来测试一下调用:
(注:参考了网络上的代码)
1
declare
@i
int
2 declare @strRet varchar ( 50 )
3 declare @strRetCode int
4 DECLARE @strErr varchar ( 255 )
5 DECLARE @strErr1 varchar ( 255 )
6 /* 首先创建Com 实例 */
7 exec @strRetCode = sp_OACreate "Project4.Cotest", @i out
8 IF @strRetCode <> 0
9 BEGIN
10 /* 创建实例 失败 */
11 EXEC sp_OAGetErrorInfo @i , @strErr OUT, @strErr1 OUT
12 PRINT ' 创建实例失败,失败的原因是: ' + @strErr + '' + @strErr1
13 RETURN
14 END
15 /* 创建成功,开始调用 */
16 EXEC @strRetCode = sp_OAMethod @i , ' Hello ' , @strRet OUT, ' Garfield '
17 IF @strRetCode <> 0
18 BEGIN
19 /* 调用方法出错 */
20 EXEC sp_OAGetErrorInfo @i , @strErr OUT, @strErr1 OUT
21 PRINT ' 调用方法失败,失败的原因是:: ' + @strErr + @strErr1
22 EXEC sp_OADestroy @i
23 RETURN
24 END
25 PRINT ' 返回的结果是: ' + @strRet
26 exec sp_OADestroy @i
2 declare @strRet varchar ( 50 )
3 declare @strRetCode int
4 DECLARE @strErr varchar ( 255 )
5 DECLARE @strErr1 varchar ( 255 )
6 /* 首先创建Com 实例 */
7 exec @strRetCode = sp_OACreate "Project4.Cotest", @i out
8 IF @strRetCode <> 0
9 BEGIN
10 /* 创建实例 失败 */
11 EXEC sp_OAGetErrorInfo @i , @strErr OUT, @strErr1 OUT
12 PRINT ' 创建实例失败,失败的原因是: ' + @strErr + '' + @strErr1
13 RETURN
14 END
15 /* 创建成功,开始调用 */
16 EXEC @strRetCode = sp_OAMethod @i , ' Hello ' , @strRet OUT, ' Garfield '
17 IF @strRetCode <> 0
18 BEGIN
19 /* 调用方法出错 */
20 EXEC sp_OAGetErrorInfo @i , @strErr OUT, @strErr1 OUT
21 PRINT ' 调用方法失败,失败的原因是:: ' + @strErr + @strErr1
22 EXEC sp_OADestroy @i
23 RETURN
24 END
25 PRINT ' 返回的结果是: ' + @strRet
26 exec sp_OADestroy @i
注意,只有 sysadmin 固定服务器角色的成员才能执行 sp_OACreate。
执行一下,看到COM组件成功地在储存过程中返回了结果.
(测试环境:Win7+Delphi2010+SQL Server 2000)