日期:2014-04-30 浏览次数:20504 次
SQL Server的T-SQL编程语言在数据存储和恢复方面功能强大,但在与SQL Server数
据库之外的系统交互方面则功能较弱。然而,我们可以通过SQL Server内置的COM自动操作环
境来克服这个限制,SQL Server内置的COM自动操作环境可以使用户在存储过程中自动操作
COM对象。在SQL Server 7.0和SQL Server 6.5中提供了7个扩展的存储过程,可以通过自己开
发的或Office等现成的COM对象扩展SQL Server的功能。SQL Server还提供了一种错误处理机
制,可以把出错信息写到SQL代理日志中。利用COM自动化操作服务,还可以把SQL Server与微
软的Exchange Server、Index Server和其他可以通过COM自动化操作服务控制其他软件进行集
SQL Server 6.5引进了对象自动操作环境,它最初被称作OLE。随着时间的变迁对象
操作的名称也有所变化,然而与SQL Server 6.5相比,SQL Server 7.0中的自动操作环境没有
改变,因此微软的文档中仍然把这一功能称作OLE操作而不是COM操作,在查阅SQL Server在
线手册(BOL)时尤其需要注意这一点。下面我们来讨论如何使用SQL Server的COM自动操作
存储过程以及COM自动操作如何帮助我们解决现实的编程问题。
COM操作的细节
表1列出了SQL Server中的7个用于COM操作的扩展存储过程。当自动操作一个COM对
象时,需要首先通过调用sp_OACreate建立一个COM对象的实例,然后通过一系列的
sp_OAGetProperty、sp_OASetProperty和sp_OAMethod调用完成需要完成的任务,在完成对
COM对象的操作后,还需要调用sp_OADestroy释放该对象。在详细地研究每个储存过程时,请
注意二个很重要的问题。第一,必须提供调用的所有参数,因为自动操作功能不支持有名参数
,如果不能使用一个详细的参数,需要向它传递一个NULL作为占位符;第二,每个调用返回一
个整数类型的HRESULT,如果调用成功则该值为0。在后面,我们将讨论如何处理返回值为非
存储过程 描述
sp_OACreate 建立自动操作对象的一个实例
sp_OADestroy 释放一个对象的实例
sp_OAGetErrorInfo 从其他过程返回的HRESULT中获得错误描述信息
sp_OAGetProperty 把一个对象的属性存储在结果集或局部变量中
sp_OASetProperty 改变一个对象属性的值
sp_OAMethod 执行对象的方法,向方法传递参数,并得到返回值
sp_OAStop 关闭SQL Server的自动操作环境
表 1: SQL Server的COM自动操作存储过程
COM操作必须以调用sp_OACreate存储过程开始,语法格式如下所示:
sp_OACreate progid | clsid, objecttoken OUT.PUT,
[context:]
第一个参数是程序ID(ProgID━━一个应用程序名.类名形式的字符串,例如
Excel.Application,)或者一个类ID(CLSID━━一个nnnnnnnn-nnn
n-nnnn-nnnn-nnnnnnnnnnnn形式的全球唯一的ID),它标明你希望创建实例的COM对象。在可
能的情况下,我建议使用ProgID参数,因为它易于输入和记忆。你会发现,只有很少的希望自
动操作的对象没有ProgID,如果偶尔碰上这样的对象,就只有使用CLSID了。第二个变量
objecttoken也是一个整型变量,一个对象的标记是指向SQL Server创建的对象的句柄和指针
,我们需要在随后的对对象的自动操作中使用这个返回的对象标记来确定这个对象。最后的
context变量是可选的,可以强迫创建的对象使用某种自动操作的机制。如果其值为1,则要
求对象在一个ActiveX DLL文件中;值为4,则要求对象在ActiveX EXE服务器中;如果是缺省
的值5,则可以使用任一自动操作。在这里我们建议使用缺省的选项,而无须为context参数
提供一个恰当的值。下面调用op_OACreate 的命令将创建一个微软的Excel程序的实例:
Declare @Object int
Declare @RetVal int
Exec @RetVal=sp_OACreate 'Excel.Application',
@Object OUTPUT
在创建一个对象后,需要获取其一些属性。要得到这些属性,可以通过下面的语法调
sp_OAGetProperty:
sp_OAGetProperty objecttoken, propertyname[, propertyvalue OUTPUT] [,
第一个参数objecttoken的值就是由sp_OACreate返回的值,参数Propertyname是我
们希望获取的属性。在获取这个值是有几种选择,如果该属性是一个单一的值,可以把它存储
在一个变量中,或者把它作为一个单行、单字段的结果集;如果属性值是一个一维或二维的数
组,则必须把它作为一个结果集;如果如果该属性的值是一个多于二维的数组,
sp_OAGetProperty就不能返回它的值,会出现一个错误。要返回一个结果集,只须简单地不指
定propertyvalue参数的值即可(如果需要它有一个值以便使用index参数,就把NULL赋给它
好了。),否则的话,应该赋给propertyvalue一个适当的类型的值,并且一定要把该参数标
记为OUTPUT。如果你访问的属性是一个集合,就需要使用index参数指定这个集合中一个特定
的数字。如果一个对象的属性是另一个对象,就应该把这个对象存入一个整数型变量中,
sp_OAGetProperty返回的也是一个对象标记,不过与sp_OACreate返回的并不相同。我们可以
使用这个对象标记对存储过程返回的任何对象进行自动化操作。下面的命令调用
sp_OAGetProperty把一个名字为DefaultFilePath的属性值存入变量@DFP中:
Exec sp_OAGetProperty @Object, 'DefaultFilePath',
@DFP OUTPUT
可以通过如下格式使用sp_OASetProperty存储过程改变一个对象的属性值:
sp_OASetProperty objecttoken, propertyname,newvalue [, index]
第一个参数objecttoken是由sp_OACreate返回的,参数Propertyname是要改变的对象的属
性名字,Newvalue参数是想赋给属性的新变量,可以是一个变量或一个文字值。如果设定的属
性值是作为一个集合的一个对象,可以使用可选的index参数来指定这个集合的一个特定的位
置。下面的命令调用sp_OASetProperty把名字为FixedDecimalPlaces的属性设置为6:
Exec sp_OASetProperty @Object, 'FixedDecimalPlaces', 6
可以用下面的语法调用sp_OAMethod存储过程执行一个对象的方法:
sp_OAMethod objecttoken, methodname [, returnvalue OUTPUT] [,
Sp_OAMethod是最灵活的,因而也是最复杂的自动操作存储过程,我们甚至可以用它象调
用一个方法那样调用一个属性,而且还能得到一个返回值,当然,我们也能使用
sp_OAGetProperty来完成这一任务。该存储过程的第一个参数objecttoken是由sp_OACreate返
回的对象标记,参数method