65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (19投票s)

2009年8月22日

CPOL

5分钟阅读

viewsIcon

41564

downloadIcon

261

本文将介绍如何将 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 作为信息消息写入指定的已注册事件日志。

参数

  1. 事件日志名称(作为 string
  2. 消息源(作为 string
  3. 消息详情(作为 string

Info_message

图 1 显示了“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 作为警告消息写入指定的已注册事件日志。

参数

  1. 事件日志名称(作为 string
  2. 消息源(作为 string
  3. 消息详情(作为 string

图 2 显示了“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 作为失败审核消息写入指定的已注册事件日志。

参数

  1. 事件日志名称(作为 string
  2. 消息源(作为 string
  3. 消息详情(作为 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 作为成功审核消息写入指定的已注册事件日志。

参数

  1. 事件日志名称(作为 string
  2. 消息源(作为 string
  3. 消息详情(作为 string
示例代码
 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;
                    }
                }
 }

图 3 显示了“Write_SUCCESS_EventLog”和“Write_FAILUR_EventLog”方法的输出。

Write_ERROR_EventLog

此方法将用户定义的 string 作为错误消息写入指定的已注册事件日志。

参数

  1. 事件日志名称(作为 string
  2. 消息源(作为 string
  3. 消息详情(作为 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;
                    }
                } 
}

图 4 显示了“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

结论

我希望本文对您有所帮助。 祝您愉快!

参考

要点

注册 COM+ 时,必须使用 Visual Studio 命令提示符执行以下命令。

命令:

C:\Program Files\Microsoft Visual Studio 9.0\VC> 
	RegAsm OLEExample.dll /tlb:OLEExample.tlb /codebase 

注意:请勿使用 regsvr32 注册 COM+。

历史

  • 2009 年 8 月 23 日:初次发布
© . All rights reserved.