我使用SQL Server 2008和ASP.NET C#,並且我有一個存儲過程返回一些計算行。SQL Server和如何處理沒有衝突的錯誤類型
我想在執行該過程之前檢查參數值,並且如果參數值錯誤,我想返回自定義錯誤消息。
在UI方面,我必須根據錯誤類型返回不同的文本並使用不同的窗口。例如:
- 參數值錯誤時出錯。
- 未處理錯誤。
我目前在數據庫中使用這種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有錯誤。
我有一些想法,但我只是想知道你的觀點和最好的方式來做到這一點。
謝謝。
所以在你的建議中,'檢查'SP被稱爲2次。但這是個好主意!有沒有辦法做到這一點,保持「檢查」邏輯在同一個SP比過程?我的意思是,有時候比起在sp開頭的兩個日期來比較它並不容易,它可能在sp的結尾。 – Dan
是的,在我的例子中它被稱爲兩次。當然,如果SP沒有在其他地方使用,您可以完全刪除SP中的支票,並依靠客戶端應用程序始終首先調用支票。 我已經擴大了答案,給出了另一種方法 –
謝謝@Joel您的答案。實際上,我最終實現了OUTPUT參數,就像您的替代建議。這對我來說是最好的解決方案,因爲在這個階段我不使用用戶定義的消息,並且我想避免在這個項目中使用它們。 – Dan