我有一个sql代理作业,它运行一个将xml文件导入表的作业步骤。这工作得很好。我想有一个运行日志文件来记录一路上的信息和错误。目前,第一次插入到Logs表中是有效的。如果我的OPENROWSET命令失败,即1Events.xml不可用,则sql代理作业返回失败,这很好。但是,如何在退出CATCH块之前让插入到日志表中呢?
BEGIN TRY
INSERT INTO Logs (Message, Level, TimeStamp)
SELECT 'Attempting to insert contents of Events.xml into sql table (XML_Events)', 'INFO', GETDATE();
INSERT INTO XML_Events(XMLData, LoadedDateTime)
SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE()
FROM OPENROWSET(BULK '\servernamec$Events.xml', SINGLE_BLOB) AS x;
INSERT INTO Logs (Message, Level, TimeStamp)
SELECT 'Successfully inserted contents of Events.xml into sql table (XML_Events)', 'INFO', GETDATE();
END TRY
BEGIN CATCH
INSERT INTO Logs (Message, Level, TimeStamp)
SELECT 'Error inserting contents of Events.xml into sql table (XML_Events)', 'ERROR', GETDATE();
END CATCH
正如Stu(刚刚)暗示的那样,这是无法"捕获"的错误之一。很容易。但是,您可以使用的一种方法是使用延迟语句并在sys.sp_executesql
中执行它;这将导致您想要的行为:
BEGIN TRY
INSERT INTO dbo.Logs (Message, Level, TimeStamp)
SELECT 'Attempting to insert contents of Events.xml into sql table (XML_Events)', 'INFO', GETDATE();
DECLARE @SQL nvarchar(MAX),
@CRLF nchar(2) = NCHAR(13) + NCHAR(10);
SET @SQL = N'INSERT INTO dbo.XML_Events(XMLData, LoadedDateTime)' + @CRLF +
N'SELECT CONVERT(XML, BulkColumn) AS BulkColumn, GETDATE()' + @CRLF +
N'FROM OPENROWSET(BULK ''\servernamec$Events.xml'', SINGLE_BLOB) AS x;';
EXEC sys.sp_executesql @SQL;
INSERT INTO dbo.Logs (Message, Level, TimeStamp)
SELECT 'Successfully inserted contents of Events.xml into sql table (XML_Events)', 'INFO', GETDATE();
END TRY
BEGIN CATCH
INSERT INTO dbo.Logs (Message, Level, TimeStamp)
SELECT 'Error inserting contents of Events.xml into sql table (XML_Events)', 'ERROR', GETDATE();
--Throw; --?
END CATCH
请注意,如果CATCH
中没有出现某种错误,SQL Agent将不知道批处理失败,因此CATCH
中的--Throw; --?
。