如何将 OLE 对象集成到 SQL Server






4.92/5 (31投票s)
本文将演示如何将 T-SQL 与外部应用程序集成。
引言
本文将演示如何将 T-SQL 与外部应用程序集成。
背景
当我们需要在 SQL Server 数据库中存储或检索数据时,我们会使用 T-SQL。但关键是如何将 T-SQL 与外部应用程序集成?例如,我们想将 SQL Server 与 Microsoft Word、Excel 或 Microsoft Exchange Server 集成。那么如何实现呢?
Using the Code
有七个扩展存储过程可以调用外部应用程序,例如 DLL。这些存储过程的名称和描述如下:
存储过程 | 描述 |
sp_OACreate |
在 Microsoft SQL Server 的实例上创建 OLE 对象实例 |
sp_OADestroy |
销毁已创建的 OLE 对象 |
sp_OAGetErrorInfo |
获取 OLE 自动化错误信息 |
sp_OAGetProperty |
获取 OLE 对象的属性值 |
sp_OASetProperty |
将 OLE 对象的属性设置为新值 |
sp_OAMethod |
调用 OLE 对象的方法 |
sp_OAStop |
停止全局 OLE 自动化存储过程执行环境 |
参考:SQL Server Books Online。
让我们用一个简单的例子来实现这一点。我们的要求是从 SQL Server 存储过程中访问第三方 DLL。
以下是使用 C# .NET 开发的两个函数。
函数 (a) getOSPlatform
将返回系统平台,函数 (b) writeToFile
将使用参数给定的值将文本写入名为 CLRTempE.txt 的文本文件中。
示例 COM+ 代码 (C#. NET)
public string getOSPlatform()
{ // Return the System Platform.
return Convert.ToString(System.Environment.OSVersion.Platform);
}
public int writeToFile(
string strPath
, string strText)
{
int intResult = -1;
try
{
if (strPath != "")
{
if (System.IO.File.Exists(strPath))
{
FileStream stream = new FileStream(
strPath
, FileMode.Open
, FileAccess.Write);
StreamWriter writer = new StreamWriter(stream);
writer.BaseStream.Seek(0, SeekOrigin.End);
writer.Write("TimeStamp: [ "
+ Convert.ToString(System.DateTime.Now)
+ " ] "
+ strText
+ " || (:-> || Info ! [Successfully inserted.]");
writer.Write(Environment.NewLine);
writer.Flush();
writer.Close();
}
else
{
FileStream stream = new FileStream(
strPath
, FileMode.CreateNew
, FileAccess.Write);
StreamWriter writer = new StreamWriter(stream);
writer.BaseStream.Seek(0, SeekOrigin.End);
writer.Write("TimeStamp: [ "
+ Convert.ToString(System.DateTime.Now)
+ " ] "
+ strText
+ " || (:-> || Info ! [Successfully inserted.]");
writer.Write(Environment.NewLine);
writer.Flush();
writer.Close();
}
intResult = 0;
}
}
catch (Exception ex)
{ throw ex; }
return intResult;
}
示例 SQL 存储过程
--EXEC dbo.spCLRExample
CREATE PROCEDURE dbo.spCLRExample
AS
BEGIN
DECLARE @intResult INT
DECLARE @comHandle INT
DECLARE @errorSource VARCHAR(8000)
DECLARE @errorDescription VARCHAR(8000)
DECLARE @inputText VARCHAR(500)
DECLARE @OSPlatform VARCHAR(500)
DECLARE @isSuccess INT
set @inputText = 'This is a simple text.'
EXEC @intResult = sp_OACreate 'CLRExample.Example', @comHandle OUTPUT, 4
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, _
@errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
-- Call a method into the component
EXEC @intResult = sp_OAMethod @comHandle, 'getOSPlatform',@OSPlatform OUTPUT
Print @OSPlatform
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle, @errorSource OUTPUT, _
@errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
-- Call a method into the component
EXEC @intResult = sp_OAMethod @comHandle, _
'writeToFile',@isSuccess OUTPUT, 'C:\CLRTempE.txt', @inputText
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle, _
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
-- Release the reference to the COM object */
EXEC sp_OADestroy @comHandle
END
GO
现在我们将讨论上述代码的工作原理。sp_OACreate
将创建 DLL 到 SQL Server 的实例。如果成功创建,则输出为 0。如果非零,则将其发送到 sp_OAGetErrorInfo
并获取错误消息。sp_OAMethod
用于调用 DLL 的方法。在第一种情况下,我们调用只具有返回值的方法 getOSPlatform
。sp_OACreate
的最后一个参数必须是 1、4 或 5。它指定新创建的 OLE 对象运行的执行上下文。如果指定,此值必须是以下值之一:
- 1 = 仅进程内 (.dll) OLE 服务器
- 4 = 仅本地 (.exe) OLE 服务器
- 5 = 允许进程内和本地 OLE 服务器
如果未指定,则默认值为 5。
如果允许进程内 OLE 服务器(通过使用上下文值 1 或 5 或不指定上下文值),它就可以访问 SQL Server 拥有的内存和其他资源。进程内 OLE 服务器可能会损坏 SQL Server 内存或资源,并导致不可预测的结果,例如 SQL Server 访问冲突。
当我们指定上下文值 4 时,本地 OLE 服务器无法访问任何 SQL Server 资源,也无法损坏 SQL Server 内存或资源。最后,sp_OADestroy
将销毁 SQL Server 中已创建的 OLE 对象。
参考 SQL Server Books Online。
兴趣点
注册 COM+ 时,我们必须使用 Visual Studio 命令提示符执行以下命令:
Commands
C:\Program Files\Microsoft Visual Studio 9.0\VC> RegAsm CLRExample.dll \ tlb: CLRExample.tlb \ codebase
注意:注册 COM+ 时不要使用 regsvr32。
结论
我希望这篇文章对您有所帮助。尽情享受吧!
历史
- 2009 年 6 月 15 日: 初始发布