在SQL中調(diào)用COM對(duì)象
2024-07-21 02:06:22
供稿:網(wǎng)友
在sqlserver中創(chuàng)建 ole 對(duì)象實(shí)例,有時(shí)我們想到數(shù)據(jù)庫中執(zhí)行存儲(chǔ)過程的時(shí)候,同時(shí)調(diào)用系統(tǒng)中的com對(duì)象。此時(shí)我們可以采用sql的系統(tǒng)存儲(chǔ)過程sp_oacreate ,此存儲(chǔ)過程的調(diào)用要有一定的權(quán)限,只有 sysadmin 固定服務(wù)器角色的成員才能執(zhí)行 sp_oacreate。
語法
sp_oacreate progid, | clsid,
objecttoken output
[ , context ]
參數(shù)
progid
是要?jiǎng)?chuàng)建的 ole 對(duì)象的程序標(biāo)識(shí)符 (progid)。此字符串描述該 ole 對(duì)象的類,其形式如下:
'olecomponent.object'
olecomponent 是 ole 自動(dòng)化服務(wù)器的組件名稱,object 是 ole 對(duì)象名。指定的 ole 對(duì)象必須有效并且必須支持 idispatch 接口。
例如,sqldmo.sqlserver 是 sql-dmo sqlserver 對(duì)象的 progid。sql-dmo 的組件名稱為 sqldmo,sqlserver 對(duì)象是有效的,并且同所有 sql-dmo 對(duì)象一樣,sqlserver 對(duì)象支持 idispatch。
clsid
是要?jiǎng)?chuàng)建的 ole 對(duì)象的類標(biāo)識(shí)符 (clsid)。此字符串描述該 ole 對(duì)象的類,其形式如下:
'{nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnnn}'
指定的 ole 對(duì)象必須有效并且必須支持 idispatch 接口。
例如,{00026ba1-0000-0000-c000-000000000046} 是 sql-dmo sqlserver 對(duì)象的 clsid。
objecttoken output
是返回的對(duì)象令牌,并且必須是數(shù)據(jù)類型為 int 的局部變量。該對(duì)象令牌用于標(biāo)識(shí)所創(chuàng)建的 ole 對(duì)象,并將在調(diào)用其它 ole 自動(dòng)化存儲(chǔ)過程時(shí)使用。
context
指定新創(chuàng)建的 ole 對(duì)象要在其中運(yùn)行的執(zhí)行上下文。如果指定,那么此值必須為下列值之一:
1 = 僅為進(jìn)程內(nèi) (.dll) ole 服務(wù)器
4 = 僅為本地 (.exe) ole 服務(wù)器
5 = 進(jìn)程內(nèi) ole 服務(wù)器和本地 ole 服務(wù)器均可
如果未指定,其默認(rèn)值為 5。此值將在調(diào)用 cocreateinstance 時(shí)作為 dwclscontext 參數(shù)傳遞。
若允許使用進(jìn)程內(nèi) ole 服務(wù)器(通過使用上下文值 1 或 5 或者不指定上下文值),該服務(wù)器將可以訪問 sql server 擁有的內(nèi)存和其它資源。進(jìn)程內(nèi) ole 服務(wù)器可能會(huì)破壞 sql server 的內(nèi)存或資源并導(dǎo)致不可預(yù)知的結(jié)果,如 sql server 訪問違規(guī)。
當(dāng)上下文值指定為 4 時(shí),本地 ole 服務(wù)器不能訪問任何 sql server 資源,因而不能破壞 sql server 的內(nèi)存或資源。
說明 此存儲(chǔ)過程的參數(shù)按位置指定,而不是按名稱指定。
返回代碼值
0(成功)或非零數(shù)字(失敗),是由 ole 自動(dòng)化對(duì)象返回的 hresult 的整數(shù)值。
我們來看一下一個(gè)具體的示例,在此示例中我們將調(diào)用一個(gè)自己寫的com組件,此組件的功能是提供讀寫序列號(hào)的功能。
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)
-- 創(chuàng)建一個(gè)com對(duì)象
exec @hr = sp_oacreate 'securitysn.csecurity', @object out
if @hr <> 0
begin
set @encryption='err'
return
end
-- 調(diào)用方法
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 -- 指明注冊(cè)讀取方式
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 -- 指明是哪種方式讀取注冊(cè)號(hào)的
end
end
-- 銷毀此對(duì)象
exec @hr = sp_oadestroy @object
if @hr <> 0
begin
set @encryption='err'
return
end
set @[email protected]
go
為了防止用戶修改存儲(chǔ)過程的代碼。我們可以將此存儲(chǔ)過程進(jìn)行加密處理。但是加密后的存儲(chǔ)過程也可能被破譯出來。