首页 > 开发 > 综合 > 正文

在SQL中调用COM对象

2024-07-21 02:06:22
字体:
来源:转载
供稿:网友


在sqlserver中创建 ole 对象实例,有时我们想到数据库中执行存储过程的时候,同时调用系统中的com对象。此时我们可以采用sql的系统存储过程sp_oacreate ,此存储过程的调用要有一定的权限,只有 sysadmin 固定服务器角色的成员才能执行 sp_oacreate。

语法
sp_oacreate progid, | clsid,
    objecttoken output
    [ , context ]

参数
progid

是要创建的 ole 对象的程序标识符 (progid)。此字符串描述该 ole 对象的类,其形式如下:

'olecomponent.object'

olecomponent 是 ole 自动化服务器的组件名称,object 是 ole 对象名。指定的 ole 对象必须有效并且必须支持 idispatch 接口。

例如,sqldmo.sqlserver 是 sql-dmo sqlserver 对象的 progid。sql-dmo 的组件名称为 sqldmo,sqlserver 对象是有效的,并且同所有 sql-dmo 对象一样,sqlserver 对象支持 idispatch。

clsid

是要创建的 ole 对象的类标识符 (clsid)。此字符串描述该 ole 对象的类,其形式如下:

'{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}'

指定的 ole 对象必须有效并且必须支持 idispatch 接口。

例如,{00026ba1-0000-0000-c000-000000000046} 是 sql-dmo sqlserver 对象的 clsid。

objecttoken output

是返回的对象令牌,并且必须是数据类型为 int 的局部变量。该对象令牌用于标识所创建的 ole 对象,并将在调用其它 ole 自动化存储过程时使用。

context

指定新创建的 ole 对象要在其中运行的执行上下文。如果指定,那么此值必须为下列值之一:

1 = 仅为进程内 (.dll) ole 服务器
4 = 仅为本地 (.exe) ole 服务器
5 = 进程内 ole 服务器和本地 ole 服务器均可

如果未指定,其默认值为 5。此值将在调用 cocreateinstance 时作为 dwclscontext 参数传递。

若允许使用进程内 ole 服务器(通过使用上下文值 1 或 5 或者不指定上下文值),该服务器将可以访问 sql server 拥有的内存和其它资源。进程内 ole 服务器可能会破坏 sql server 的内存或资源并导致不可预知的结果,如 sql server 访问违规。

当上下文值指定为 4 时,本地 ole 服务器不能访问任何 sql server 资源,因而不能破坏 sql server 的内存或资源。

 

说明  此存储过程的参数按位置指定,而不是按名称指定。


返回代码值
0(成功)或非零数字(失败),是由 ole 自动化对象返回的 hresult 的整数值。

我们来看一下一个具体的示例,在此示例中我们将调用一个自己写的com组件,此组件的功能是提供读写序列号的功能。

create procedure [dbo].[sp_mychecksn]
@encryption nvarchar(255) out,@type int out
  as
 declare @object int
declare @hr int
declare @property varchar(255)
declare @return varchar(255)
declare @src varchar(255), @desc varchar(255)

-- 创建一个com对象
exec @hr = sp_oacreate 'securitysn.csecurity', @object out
if @hr <> 0
begin
 set @encryption='err'
     return
end

-- 调用方法
declare @aa  nvarchar(255)  -- 最终返回的值
exec @hr = sp_oamethod @object, 'getdisksn', @aa out
if @hr <> 0
begin
 set @encryption='err'
     return
end
else
begin
 set  @type=8 -- 指明注册读取方式
end

---------------------
if @aa=''
begin
 -- 再读一次
 exec @hr = sp_oamethod @object, 'getsnbyapi', @aa out
 if @hr<>0
  begin
   set @encryption='err'
       return
  end
 else
 begin
  set @type=5 -- 指明是哪种方式读取注册号的
 end
end

-- 销毁此对象
exec @hr = sp_oadestroy @object
if @hr <> 0
begin
  set @encryption='err'
     return
end
set @[email protected]
go


为了防止用户修改存储过程的代码。我们可以将此存储过程进行加密处理。但是加密后的存储过程也可能被破译出来。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表