Ошибка SQL не возвращается обратно вызывающей стороне
Я новичок в этом форуме, но, пожалуйста, потерпите меня. У меня есть форма aC# Windows, на которой есть два флажка. Один из них называется chkThrowError, а другой - chkDivideError, оба флажка не установлены. Эти элементы управления предназначены исключительно для управления выполнением хранимой процедуры. У меня есть кнопка Button со следующим кодом:
private void cmdError_Click(object sender, EventArgs e)
{
int ThrowError = 0;
int DividByZero = 0;
if (chkThrowError.Checked)
{
ThrowError = 1;
}
if (chkDivideError.Checked)
{
DividByZero = 1;
}
try
{
clsBBFinances.TestError(ThrowError,DividByZero);
MessageBox.Show("Everything is Hunkey Dorey");
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
}
}
clsBBFinances - это мой бизнес-объект, а процедура TestError выглядит следующим образом:
public static void TestError(int ThrowError, int ThrowDivideError)
{
System.Data.SqlClient.SqlDataReader objRs = null;
string strsql = "";
bool Success = true;
string ErrMsg = "";
int intCount = 0;
try
{
strsql = strsql + "Exec ";
strsql = strsql + "TestError " + ThrowError.ToString() + " , " + ThrowDivideError.ToString();
objRs = clsBBFinances.TheDatabase.ExecuteReadOnly(strsql);
while (objRs.Read())
{
intCount++;
object xxx = objRs[0];
}
Success = true;
ErrMsg = "";
//intCount = objRs.RecordsAffected;
}
catch (Exception ex)
{
ErrMsg = ex.Message;
intCount = 0;
Success = false;
throw ex;
}
finally
{
if (objRs != null)
{
if (!objRs.IsClosed)
{
objRs.Close();
}
}
}
}
Пожалуйста, примите синтаксис, чтобы быть правильным, и у меня есть допустимое соединение SQL (sql2008(R2))
Это в основном вызывает следующую хранимую процедуру:
Create PROCEDURE TestError
(@ThrowError int=0
,@ThrowDivideError int= 0
)
AS
BEGIN
SET NOCOUNT ON;
Declare @x int
Declare @y int
Declare @ErrorNumber int
Declare @ErrorMessage varchar(2000)
Declare @ErrorSeverity int
Declare @ErrorState int
Begin Try
If isnull(@ThrowError,0) <> 0
Begin
RaisError ('Forced Error Raised',16,1)
Return
End
If isnull(@ThrowDivideError,0) <>0
Begin
set @x = 5
Set @y =0
Select @x/@y as z
End
End Try
Begin catch
Select @ErrorNumber = Error_Number()
,@ErrorMessage = 'Test Error ' + Error_message()
,@Errorseverity= Error_Severity()
,@ErrorState = Error_State()
RaisError (@Errormessage, @ErrorSeverity, @ErrorState)
--THROW 51000, @Errormessage, @ErrorState;
Return
End Catch
Select * from information_Schema.tables
END
GO
По сути, я поднимаю ошибку, зависящую от параметра, переданного в.. Если мой первый параметр не равен нулю, я выдаю пользовательскую ошибку, а если первый равен 0, а второй ненулевой, тогда я выполняю деление на ноль, чтобы сгенерировать меня Системная ошибка. Если оба равны нулю, я делаю простой выбор из Information_Schema.tables, чтобы закончить его. Цель хранимой процедуры - вызвать МОЮ ошибку и системную ошибку.
Когда я вызываю процедуру, и мой первый аргумент устанавливается в 1, возникает моя пользовательская ошибка, которая проходит через блок перехвата SQl и впоследствии перехватывается в моем блоке перехвата в C#.
Однако, когда я выполняю его со вторым аргументом, установленным в 1, ошибка деления на ноль перехватывается в блоке перехвата SQL, но НЕ перехватывается блоком перехвата в C#. Код продолжается, как будто ошибки не произошло.
Я хочу быть в состоянии поймать вторую ошибку.. Кто-нибудь знает, как. Пожалуйста, не стесняйтесь вставлять приведенный выше код и попробуйте его сами.
Принудительная ошибка я получаю сообщение Test Error Forced Error Raised
,
Разделить на ноль я получаю сообщение Everything is Hunkey Dorey
, это не так.
Нужна помощь пожалуйста
1 ответ
Вы используете SqlDataReader, он читает только один набор результатов за раз. Исключение происходит во втором наборе результатов. Поэтому вы должны переместить читателя ко второму набору результатов с помощью NextResult(). Тогда вы нажмете исключение...
var connection = new SqlConnection("Data Source=xxx;Initial Catalog=Test;User Id=xxx;Password=xxx");
connection.Open();
try
{
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "TestError";
command.Parameters.AddWithValue("@ThrowDivideError", 1);
var reader = command.ExecuteReader(CommandBehavior.CloseConnection);
reader.Read();
reader.NextResult();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.ReadLine();