其实大家都知道sql语句的错误信息都可以在sys.messages表里面找到
如:
如果在执行语句在try...catch中 我们可以通过以下方法获取错误信息。sql语句如下:
代码如下:@H_403_10@
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,-- Severity,-- State,
@errornumber
);
END CATCH
@H_403_10@
当然我这里是故意用RAISERROR再次抛出错误信息,运行结果如下:
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,-- Severity,-- State,
@errornumber
);
END CATCH
@H_403_10@
当然我这里是故意用RAISERROR再次抛出错误信息,运行结果如下:
现在我们来定义一个存储过程,其目的就是往本地文件中写入信息。
sql脚本如下:
代码如下:@H_403_10@
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',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',1)
EXECUTE @RetCode = sp_OAMethod @FileHandle,'WriteLine',NULL,@text
IF (@@ERROR|@RetCode > 0 )
RAISERROR ('could not write to File','Close'
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not close file ',1)
EXEC sp_OADestroy @filehandle
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not destroy file object',1)
EXEC sp_OADestroy @FileSystem
@H_403_10@
然后执行该存储过程:
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',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',1)
EXECUTE @RetCode = sp_OAMethod @FileHandle,'WriteLine',NULL,@text
IF (@@ERROR|@RetCode > 0 )
RAISERROR ('could not write to File','Close'
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not close file ',1)
EXEC sp_OADestroy @filehandle
IF (@@ERROR|@RetCode > 0)
RAISERROR ('Could not destroy file object',1)
EXEC sp_OADestroy @FileSystem
@H_403_10@
然后执行该存储过程:
代码如下:@H_403_10@
exec UCreateOrAppendTextFile 'C:\Error.log','hello majaing'
@H_403_10@
如果遇到以下错误则说明Ole Automation Procedures没有启用
@H_403_10@
如果遇到以下错误则说明Ole Automation Procedures没有启用
需要执行以下sql:
代码如下:@H_403_10@
go
sp_configure 'show advanced options',1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures',1;
GO
RECONFIGURE;
GO
@H_403_10@
运行即如果如图:
sp_configure 'show advanced options',1;
GO
RECONFIGURE;
GO
sp_configure 'Ole Automation Procedures',1;
GO
RECONFIGURE;
GO
@H_403_10@
运行即如果如图:
当然这里运行存储过程之前文件是存在的。
代码如下:@H_403_10@
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
@H_403_10@
执行存储过程及结果如下:
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
@H_403_10@
执行存储过程及结果如下:
以上存储过程在MSsql2005、2012中测试通过。
大家都知道目前在文件系统中事务的实现还是比较复杂的,虽然在win7后我们可以用C#实现文件的事务,但是微软的分布式事务Distributed Transaction Coordinator(msdtc)目前也还不支持文件事务。
这里说说为什么有这样的需求吧:目前需要一个项目用SSIS做数据迁移,其中很大部分都是用sql语句实现的, 如 insert into ....select ... from xxxx.其中原数据库中难免有什么脏数据导致插入失败,于是我在SSIS中使用msdtc服务,保证数据的一致性。虽然SSIS也有错误处理,但是它只能记录那个sql语句有问题,而不能记录具体问题。于是我想到把错误信心记录报数据库表里面,可是当遇到问题时事务会回滚,表里面根本就没有错误信息。于是乎 只能报错误信息记录到文件中了。
如:
有不对的地方还请大家拍砖哦!
原文链接:https://www.f2er.com/mssql/63493.html