Я использую SQL Server 2008 и ASP.NET C #, и у меня есть хранимая процедура, которая возвращает некоторые вычисленные строки.
Я хочу проверить значения параметров перед выполнением процесса и вернуть пользовательское сообщение об ошибке, если значения параметров неверны.
На стороне пользовательского интерфейса я должен вернуть другой текст и использовать другое окно в соответствии с типом ошибки. Пример:
- Ошибки при неправильных значениях параметров.
- Не обработанные ошибки.
В настоящее время я использую этот тип SP в базе данных, но я пытался использовать аргумент состояния и даже аргумент серьезности для определения типа ошибки. Но у меня есть некоторые конфликты с необработанной ошибкой, возвращающей тот же номер состояния, что и ошибка моего параметра, и поэтому появляется неправильное окно. Если я использую уровень серьезности, я думаю, что SP может вернуть ошибку с тем же номером серьезности, а также в некоторых случаях.
Я приведу быстрый пример, чтобы лучше рассмотреть:
CREATE PROCEDURE dbo.GetData
@Date1 date,
@Date2 date
AS
BEGIN
-- check the parameters
IF @Date2 < @Date1
BEGIN
RAISERROR(N'Date 2 cannot be less than Date 1', 16, 2); -- <= Here State 2
return
END
-- process here...
DECLARE @Table1 TABLE ( name nvarchar(50) NOT NULL)
-- Supposing you have to insert a row with a NULL value
INSERT INTO @Table1 VALUES (NULL);
-- Thus, this query returns this error with the state 2 as well!
--Msg 515, Level 16, State 2, Procedure GetData, Line 21
--Cannot insert the value NULL into column 'name', table '@Table1'; column does not allow nulls. INSERT fails.
SELECT 'Record 1';
SELECT 'Record 2';
END
Из c #:
List<string> data = new List<string>();
protected void Button1_Click(object sender, EventArgs e)
{
string errorMessage = string.Empty;
bool isErrorFromChecking = false;
if (GetValues(ConfigurationManager.ConnectionStrings["TestConnectionString"].ConnectionString,
new DateTime(2011, 01, 01), new DateTime(2011, 02, 01),
ref isErrorFromChecking, ref errorMessage))
{
Label1.Text = data[0].ToString();
return;
}
if (isErrorFromChecking)
{
Label1.Text = errorMessage;
return;
}
Label1.Text = string.Format("Internal Error: {0}.", errorMessage);
}
private bool GetValues(string connectionString, DateTime date1, DateTime date2,
ref bool isErrorFromChecking, ref string errorMessage)
{
data = new List<string>();
try
{
using (SqlConnection sqlCon = new SqlConnection(connectionString))
{
sqlCon.Open();
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.Connection = sqlCon;
sqlCmd.CommandType = CommandType.StoredProcedure;
sqlCmd.CommandText = "dbo.GetData";
sqlCmd.Parameters.AddWithValue("Date1", date1);
sqlCmd.Parameters.AddWithValue("Date2", date2);
SqlDataReader reader = sqlCmd.ExecuteReader();
while (reader.Read())
{
data.Add(reader[0].ToString());
}
reader.Close();
sqlCon.Close();
}
}
catch (SqlException ex)
{
if (ex.State == 2)
{
isErrorFromChecking = true;
errorMessage = ex.Message;
return false;
}
isErrorFromChecking = false;
errorMessage = ex.Message;
return false;
}
catch (Exception ex)
{
isErrorFromChecking = false;
errorMessage = ex.Message;
return false;
}
return true;
}
В приведенном выше коде даты верны, но программа не возвращает сообщение «Внутренняя ошибка:…», хотя SP имеет ошибку.
У меня есть некоторые идеи, но я просто хочу знать вашу точку зрения и лучший способ сделать это.
Спасибо.