如何将 OLE 对象与 SQL Server v2 集成






4.97/5 (19投票s)
本文将介绍如何将 OLE 对象(COM+ API)与 SQL Server 集成,并将消息写入 Windows 事件日志。
目录
引言
如果您阅读过我的一些 CodeProject 文章,您可能知道我并不吝啬与大家分享我学到的东西。事实上,如果我发现什么有趣的事情,我总是会尝试与大家分享。我写文章的经验不多,但因为 CodeProject 这个精彩的知识分享平台,我一直在努力。我希望大家都会同意,CodeProject 为我们提供了一个绝佳的知识分享平台。
在详细介绍本文之前,我想分享一个小插曲;几个月前,我在更新一个 ERP 系统时,发现 Transact-SQL 和表设计存在大量错误。大多数时候,系统都无法处理数据事务。为了找出原因,我指派了一位团队成员。几天后,他向我汇报说,一些主要原因包括数据类型不匹配、数据转换错误、存储过程参数问题等等。因此,我们决定首先必须找出错误的来源和错误类型。那么,我们如何才能做到这一点呢?
当我们开始着手这项工作时,我们非常困惑,是维护一个文本文件来记录日志,还是创建一个表来存储日志?但问题是,将有许多存储过程与各种 OLE 对象一起工作。所以,最终我们决定需要使用 Windows 事件日志 API。本文将介绍如何使用 Transact-SQL 创建 Windows 事件日志并写入自定义消息。
关于 OLE 对象的基本知识
当我开始学习 Microsoft OLE 对象时,我在在线资源,尤其是 Microsoft Development Network (MSDN) 上找到了大量的理论解释。我在这里尝试给大家做一些总结。
您也可以在我的一篇 CodeProject 文章中找到更多关于 OLE 自动化的详细信息。链接如下
什么是 OLE 对象
OLE(Object Linking and Embedding,对象链接与嵌入)是 Microsoft 的复合文档技术框架。简而言之,复合文档就像一个显示桌面,可以包含各种类型的视觉和信息对象:文本、日历、动画、声音、动态视频、3D、持续更新的新闻、控件等等。每个桌面对象都是一个独立的程序实体,可以与用户交互,也可以与桌面上的其他对象通信。作为 Microsoft ActiveX 技术的一部分,OLE 利用了更广泛、更通用的概念——组件对象模型 (COM) 及其分布式版本 DCOM。OLE 对象必然也是一个组件(或 COM 对象)。
因此,我们可以将 OLE 对象定义为:“OLE 是由 Microsoft Corporation 开发的一种复合文档标准。它使您能够在一个应用程序中创建对象,然后将它们链接或嵌入到第二个应用程序中。嵌入式对象保留其原始格式以及创建它们的应用程序的链接。”
更多详情请访问 此链接。
使用代码
这是一个非常简单的方法。我编写了一些方法来创建或向 Windows 事件日志写入任何自定义消息。下面是这些方法及其简要说明
方法
GetAuthor
IsExist
CreateLog
Write_INFO_EventLog
Write_WARNING_EventLog
Write_FAILUR_EventLog
Write_SUCCESS_EventLog
Write_ERROR_EventLog
更多详情请访问 此链接。
GetAuthor
这是一个简单的方法,实际上,当我开始编写代码时,我首先写了这个方法,它只返回一个 string
类型的数据。这只是为了测试目的。
IsExist
此方法将检查请求的日志名称是否已注册。如果已注册,则返回 true
,否则返回 false
。
参数: string_expression
是一个 string
/ varchar
类型的表达式
返回类型: bool
示例代码
private bool IsExist(string strLogName)
{
bool Reasult = false;
if (System.Diagnostics.EventLog.SourceExists(strLogName)) return Reasult = true;
return Reasult;
}
CreateLog
如果请求的日志名称未注册,此方法将创建一个新的 Windows 事件日志。一旦成功注册日志,它将返回 true
,否则返回 false
。
参数(日志名称): string_expression
是一个 string
/ varchar
类型的表达式
返回类型: bool
示例代码
public bool CreateLog(string strLogName)
{
bool Reasult = false;
try
{
if (!this.IsExist(strLogName))
{
System.Diagnostics.EventLog.CreateEventSource(strLogName, strLogName);
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
SQLEventLog.Source = strLogName;
SQLEventLog.Log = strLogName;
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry("The " + strLogName +
" was successfully initialize component.",
EventLogEntryType.Information);
Reasult = true;
}
}
catch
{
Reasult = false;
}
return Reasult;
}
Write_INFO_EventLog
此方法将用户定义的 string
作为信息消息写入指定的已注册事件日志。
参数
- 事件日志名称(作为
string
) - 消息源(作为
string
) - 消息详情(作为
string
)
Write_INFO_EventLog
”方法的输出。示例代码
public void Write_INFO_EventLog(string strLogName
, string strSource
, string strErrDetail)
{
if (this.IsExist(strLogName))
{
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
try
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString(strSource)
+ Convert.ToString(strErrDetail),
EventLogEntryType.Information);
}
catch (Exception ex)
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString("INFORMATION: ")
+ Convert.ToString(ex.Message),
EventLogEntryType.Information);
}
finally
{
SQLEventLog.Dispose();
SQLEventLog = null;
}
}
}
Write_WARNING_EventLog
此方法将用户定义的 string
作为警告消息写入指定的已注册事件日志。
参数
- 事件日志名称(作为
string
) - 消息源(作为
string
) - 消息详情(作为
string
)
Write_WARNING_EventLog
”方法的输出。示例代码
public void Write_WARNING_EventLog(string strLogName
, string strSource
, string strErrDetail)
{
if (this.IsExist(strLogName))
{
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
try
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString(strSource)
+ Convert.ToString(strErrDetail),
EventLogEntryType.Warning);
}
catch (Exception ex)
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString("WARNING: ")
+ Convert.ToString(ex.Message),
EventLogEntryType.Warning);
}
finally
{
SQLEventLog.Dispose();
SQLEventLog = null;
}
}
}
Write_FAILUR_EventLog
此方法将用户定义的 string
作为失败审核消息写入指定的已注册事件日志。
参数
- 事件日志名称(作为
string
) - 消息源(作为
string
) - 消息详情(作为
string
)
示例代码
public void Write_FAILUR_EventLog(string strLogName
, string strSource
, string strErrDetail)
{
if (this.IsExist(strLogName))
{
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
try
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString(strSource)
+ Convert.ToString(strErrDetail),
EventLogEntryType.FailureAudit );
}
catch (Exception ex)
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString("FAILUR: ")
+ Convert.ToString(ex.Message),
EventLogEntryType.FailureAudit );
}
finally
{
SQLEventLog.Dispose();
SQLEventLog = null;
}
}
}
Write_SUCCESS_EventLog
此方法将用户定义的 string
作为成功审核消息写入指定的已注册事件日志。
参数
- 事件日志名称(作为
string
) - 消息源(作为
string
) - 消息详情(作为
stri
)ng
示例代码
public void Write_SUCCESS_EventLog(string strLogName
, string strSource
, string strErrDetail)
{
if (this.IsExist(strLogName))
{
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
try
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString(strSource)
+ Convert.ToString(strErrDetail),
EventLogEntryType.SuccessAudit );
}
catch (Exception ex)
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString("FAILUR: ")
+ Convert.ToString(ex.Message),
EventLogEntryType.SuccessAudit );
}
finally
{
SQLEventLog.Dispose();
SQLEventLog = null;
}
}
}
Write_SUCCESS_EventLog
”和“Write_FAILUR_EventLog
”方法的输出。Write_ERROR_EventLog
此方法将用户定义的 string
作为错误消息写入指定的已注册事件日志。
参数
- 事件日志名称(作为
string
) - 消息源(作为
string
) - 消息详情(作为
string
)
示例代码
public void Write_ERROR_EventLog(string strLogName
, string strSource
, string strErrDetail)
{
if (this.IsExist(strLogName))
{
System.Diagnostics.EventLog SQLEventLog =
new System.Diagnostics.EventLog();
try
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString(strSource)
+ Convert.ToString(strErrDetail),
EventLogEntryType.Error);
}
catch (Exception ex)
{
SQLEventLog.Source = strLogName;
SQLEventLog.WriteEntry(Convert.ToString("ERROR: ")
+ Convert.ToString(ex.Message),
EventLogEntryType.Error);
}
finally
{
SQLEventLog.Dispose();
SQLEventLog = null;
}
}
}
Write_ERROR_EventLog
”方法的输出。OLE 自动化
要了解 OLE 自动化,我建议您阅读我在 CodeProject 的文章,请访问 此链接。
Transact-SQL 脚本
-- =============================================
-- Author: Md. Marufuzzaman
-- Create date:
-- Description: Create a new Windows Event Log File and
-- Write a user define message to event log.
-- =============================================
--ALTER
CREATE PROCEDURE [dbo].[spEventLog]
AS
BEGIN
DECLARE @intResult INT
DECLARE @comHandle INT
DECLARE @errorSource VARCHAR(8000)
DECLARE @errorDescription VARCHAR(8000)
DECLARE @inputText VARCHAR(500)
DECLARE @Author VARCHAR(500)
DECLARE @isSuccess INT
--Example(1): Call a simple function [GetAuthor] which is return a string type value.
-- Create COM object
EXEC @intResult = sp_OACreate 'OLEExample.ClsExample', @comHandle OUTPUT, 1
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, 'GetAuthor',@Author OUTPUT
SELECT @Author
--End of Example(1)
--Example(2): Calling a function [CreateLog] to create a new windows
--event log name as "OLEExample".
SET @isSuccess = -1
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,
'CreateLog',@isSuccess OUTPUT, 'OLEExample'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
SELECT @isSuccess -- IF the value of @isSuccess is 1 that indicates new event
-- log is successfully created, otherwise fail to create.
--End of Example(2)
--Example(3): Calling a function to write your information into the event log.
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,
'Write_INFO_EventLog',@isSuccess OUTPUT, 'OLEExample',_
'Message source. ','Your Message.'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(3)
--Example(4): Calling a function to write your WARNING information into the event log.
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,
'Write_WARNING_EventLog',@isSuccess OUTPUT, _
'OLEExample','WARNING Message source. ','Your WARNING Message.'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(4)
--Example(5): Calling a function to write your WARNING information into the event log.
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,
'Write_FAILUR_EventLog',@isSuccess OUTPUT, 'OLEExample',_
'FAILUR Message source. ','Your FAILUR Message.'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(5)
--Example(6): Calling a function to write your SUCCESS Audit
--information into the event log.
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,
'Write_SUCCESS_EventLog',@isSuccess OUTPUT, 'OLEExample',_
'SUCCESS Audit Message source. ','Your SUCCESS Audit Message.'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(6)
--Example(7): Calling a function to write your ERROR information into the event log.
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,
'Write_ERROR_EventLog',@isSuccess OUTPUT, 'OLEExample',_
'ERROR Message source. ','Your ERROR Message.'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(7)
--Example(8): Calling a function to write your ERROR information into the event log.
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,
'Write_AUTHOR_EventLog',@isSuccess OUTPUT, 'OLEExample',_
'[dbo].[spEventLog]. ','AUTHOR: MD. MARUFUZZAMAN'
IF (@intResult <> 0)
BEGIN
-- Error Handling
EXEC sp_OAGetErrorInfo @comHandle,
@errorSource OUTPUT, @errorDescription OUTPUT
SELECT [Error Source] = @errorSource, [Description] = @errorDescription
RETURN
END
--End of Example(8)
-- Release the reference to the COM object */
EXEC sp_OADestroy @comHandle
END
GO
结论
我希望本文对您有所帮助。 祝您愉快!
参考
- SQL Server Books Online
- MSDN
- support.microsoft.com
要点
注册 COM+ 时,必须使用 Visual Studio 命令提示符执行以下命令。
命令:
C:\Program Files\Microsoft Visual Studio 9.0\VC>
RegAsm OLEExample.dll /tlb:OLEExample.tlb /codebase
注意:请勿使用 regsvr32
注册 COM+。
历史
- 2009 年 8 月 23 日:初次发布