我正在使用 C#在 File Watcher Windows服务上,该服务在特定文件夹中查找 .bak 文件,然后用它来还原文件所属的数据库。
还原的数据库具有一个存储过程,该存储过程调用10个不同的存储过程。 File Watcher's 功能是在还原完成后执行存储过程的功能。
存储过程为[1_IMPORT_DATA_AND_PROCESS_ALL]
,它本身会调用10个不同的存储过程。
// Trigger Stored Procedure after restore.
private void triggerSP(String connectionStr)
{
// This doesn't open the Connection. conn.Open() has to be explicitly called.
SqlConnection conn = new SqlConnection(connectionStr);
try
{
conn.Open();
conn.FireInfoMessageEventOnUserErrors = true;
// Capture messages returned by SQL Server.
conn.InfoMessage += delegate (object sender, SqlInfoMessageEventArgs e)
{
message += " -> " + e.Message + " -> ";
};
//conn.InfoMessage += new SqlInfoMessageEventHandler(cn_InfoMessage);
//.create a command object identifying the stored procedure.
SqlCommand cmd = new SqlCommand("[dbo].[1_IMPORT_DATA_AND_PROCESS_ALL]", conn);
cmd.CommandTimeout = 0;
// 2. set the command object so it knows to execute a stored procedure.
cmd.CommandType = CommandType.StoredProcedure;
// Add a check here as well.
// execute the command.
SqlDataReader rdr = cmd.ExecuteReader();
string[] info = new string[] { "Message: \n" + message };
WriteToFile(info);
// Since we are not using - using block we have to explicitly call Close() to close the connection.
conn.Close();
}
catch (SqlException SqlEx){
string[] error = new string[3] ;
string msg1 = "Errors Count:" + SqlEx.Errors.Count;
string msg2 = null;
foreach (SqlError myError in SqlEx.Errors)
msg2 += myError.Number + " - " + myError.Message + "/" ;
conn.InfoMessage += delegate (object sender, SqlInfoMessageEventArgs e)
{
message += "\n" + e.Message;
};
error[0] = msg1;
error[1] = msg2;
error[2] = message;
WriteToFile(error);
}
finally
{
//call this if exception occurs or not
//in this example, dispose the WebClient
conn.Close();
}
}
我只从第一个存储过程即[1_IMPORT_DATA_AND_PROCESS_ALL]
取回Message输出,而不是从[1_IMPORT_DATA_AND_PROCESS_ALL]
内部调用的存储过程取回消息,如下所示。
第一个Sp调用另一个SP后,我的代码就会停止读取消息。
我想捕获所有正在打印的消息(如下图所示),这是我在SSMS中执行SP时正在打印的实际消息。
此特定行是从SP提取消息
conn.InfoMessage += delegate (object sender, SqlInfoMessageEventArgs e)
{
message += " -> " + e.Message + " -> ";
};
到目前为止,我已经提到了this问题中的所有问题,而它是derivatives。
希望我的问题很清楚。
答案 0 :(得分:0)
美好的一天,
注意!:该消息未标记为“社区Wiki”,因此它是由特定人员以其姓名撰写的,因此不是共享文章。如果您有评论,请使用评论而不是更改OP打算提供的内容(例如,内容中的额外学习要点)。谢谢!
在下面的脚本中,我提供了一个处理嵌套存储过程错误的示例。基本思想是使用TRY / CATCH以防止引发错误并停止事务,而OUTPUT用于将错误信息返回到上层SP
这只是一个基本示例...
CREATE or ALTER PROCEDURE L1 (
@InputInt int,
@ErrMessage NVARCHAR(MAX) OUTPUT,
@ErrNum INT OUTPUT
)AS
SELECT @@NESTLEVEL AS 'Inner Level'; -- this information present the level of the SP during the execution. It is not needed for the solution but for the sake of the learning and understanding of nested SP
Select 'Start L1'
BEGIN TRY
-- When the ionput is 0 we Generate a divide-by-zero error.
SELECT 1/@InputInt;
END TRY
BEGIN CATCH
SET @ErrMessage = ERROR_MESSAGE()
SELECT @ErrMessage
END CATCH;
SET @ErrNum = @@ERROR
IF (@ErrNum > 0) Begin
SELECT 'L1 error Number: ' + CONVERT(NVARCHAR(10), @ErrNum)
Return
END
ELSE
select 'L1 OK'
GO
CREATE or ALTER PROCEDURE L2 (
@InputInt int
) AS
Declare @ErrMessage NVARCHAR(MAX) = '', @ErrNum INT = 0
SELECT @@NESTLEVEL AS 'Outer Level';
BEGIN TRY
EXEC L1 @InputInt, @ErrMessage, @ErrNum;
END TRY
BEGIN CATCH
SELECT 'There was error!'
select @@ERROR
END CATCH
GO
EXECUTE L2 1 -- OK
GO
EXECUTE L2 0; --Raise error in the nested stored procedures
GO