如何将sql 执行的错误消息 记录到本地文件中

其实大家都知道sql语句的错误信息都可以在sys.messages表里面找到

如:

如果在执行语句在try...catch中 我们可以通过以下方法获取错误信息。sql语句如下:

复制代码
BEGIN TRY
    SELECT  3 / 0
END TRY
BEGIN CATCH
    DECLARE @errornumber INT
    DECLARE @errorseverity INT
    DECLARE @errorstate INT 
    DECLARE @errormessage NVARCHAR(4000)
    SELECT  @errornumber = ERROR_NUMBER() ,
            @errorseverity = ERROR_SEVERITY() ,
            @errorstate = ERROR_STATE() ,
            @errormessage = ERROR_MESSAGE()

    SELECT  @errornumber ,
            @errorseverity ,
            @errorstate ,
            @errormessage

    RAISERROR (
             @errormessage, -- Message text,
             @errorseverity,                        -- Severity,
             @errorstate,                         -- State,
           @errornumber
          ); 
END CATCH
View Code
复制代码

当然我这里是故意用RAISERROR再次抛出错误信息,运行结果如下:

现在我们来定义一个存储过程,其目的就是往本地文件中写入信息。

sql脚本如下:

复制代码
CREATE Proc [dbo].[UCreateOrAppendTextFile](@Filename VarChar(100),@Text nVarchar(4000))
AS
DECLARE @FileSystem int
DECLARE @FileHandle int
DECLARE @RetCode int
DECLARE @RetVal int
DECLARE @CreateOrAppend int


EXECUTE @RetCode = sp_OACreate 'Scripting.FileSystemObject' , @FileSystem OUTPUT
IF (@@ERROR|@RetCode > 0 Or @FileSystem < 0)
RAISERROR ('could not create FileSystemObject',16,1)

EXECUTE @RetCode = sp_OAMethod @FileSystem , 'FileExists', @RetVal out, @FileName
IF (@@ERROR|@RetCode > 0)
RAISERROR ('could not check file existence',16,1)
-- If file exists then append else create
SET @CreateOrAppend = case @RetVal when 1 then 8 else 2 end
EXECUTE @RetCode = sp_OAMethod @FileSystem , 'OpenTextFile' , @FileHandle OUTPUT , @Filename, @CreateOrAppend, 1
IF (@@ERROR|@RetCode > 0 Or @FileHandle < 0)
RAISERROR ('could not create File',16,1)

EXECUTE @RetCode = sp_OAMethod @FileHandle , 'WriteLine' , NULL , @text
IF (@@ERROR|@RetCode > 0 )
RAISERROR ('could not write to File',16,1)

EXECUTE @RetCode = sp_OAMethod @FileHandle , 'Close'
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not close file ',16,1)

EXEC sp_OADestroy @filehandle
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not destroy file object',16,1)

EXEC sp_OADestroy @FileSystem
----------------------------------------
复制代码

然后执行该存储过程:

exec UCreateOrAppendTextFile 'C:\Error.log','hello majaing'

如果遇到以下错误则说明Ole Automation Procedures没有启用

需要执行以下SQL:

复制代码
go
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures', 1;
GO
RECONFIGURE;
GO
复制代码

运行即如果如图:

当然这里运行存储过程之前必须保证 文件是存在的

最后封装一个存储过程获取错误信息,其脚本如下:

复制代码
CREATE PROCEDURE LOGError(@msg nvarchar(400))
as 
declare @text nvarchar(400)
SELECT  @text=text FROM sys.messages WHERE language_id=1033 AND  message_id=@@ERROR
if len(@text)>1
begin
set @msg=@msg +' : '+@text
 EXEC dbo.UCreateOrAppendTextFile 'C:\Error.log',@msg
end
复制代码

执行存储过程及结果如下:

以上存储过程在MSSQL2005、2012中测试通过。

大家都知道目前在文件系统中事务的实现还是比较复杂的,虽然在win7后我们可以用C#实现文件的事务,但是微软的分布式事务Distributed Transaction Coordinator(msdtc)目前也还不支持文件事务。

这里说说为什么有这样的需求吧:目前需要一个项目用SSIS做数据迁移,其中很大部分都是用sql语句实现的, 如 insert into ....select ... from xxxx.其中原数据库中难免有什么脏数据导致插入失败,于是我在SSIS中使用msdtc服务,保证数据的一致性。虽然SSIS也有错误处理,但是它只能记录那个sql语句有问题,而不能记录具体问题。于是我想到把错误信心记录报数据库表里面,可是当遇到问题时事务会回滚,表里面根本就没有错误信息。于是乎 只能报错误信息记录到文件中了。

如:

有不对的地方还请大家拍砖哦!

 

 

 

 

 

posted on   dz45693  阅读(3018)  评论(2编辑  收藏  举报

编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构

导航

< 2013年5月 >
28 29 30 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8
点击右上角即可分享
微信分享提示