2013-06-01 79 views
1

我有一個登錄頁面,用戶有ID和ID是表中的主鍵。我也有一個管理員帳戶,管理員可以創建用戶。但是,當我用現有的ID創建用戶帳戶時,網頁崩潰。我想處理這種情況並給出警告,指出此ID存在並且無法創建。這是我的代碼:如何處理在asp.net中違反主鍵約束?

public void CreateStudent(int ID, String status, String email, String firstName, String lastName, String password, String level, String program) 
{ 
    SqlConnection con = new SqlConnection(GetConnectionString()); 


    string query1 = "insert into StudentTable(Name,Surname,ID,email,level,program,status,password,Type) values(@firstName,@lastName,@ID,@email,@level,@program,@status,@password,'Student')"; 


    SqlCommand command = new SqlCommand(query1,con); 

    command.Parameters.AddWithValue("@firstName", firstName); 
    command.Parameters.AddWithValue("@lastName", lastName); 
    command.Parameters.AddWithValue("@ID", ID); 
    command.Parameters.AddWithValue("@email", email); 
    command.Parameters.AddWithValue("@level", level); 
    command.Parameters.AddWithValue("@program", program); 
    command.Parameters.AddWithValue("@status", status); 
    command.Parameters.AddWithValue("@password", password); 

    int result; 
    con.Open(); 
    result = command.ExecuteNonQuery(); 
    con.Close(); 


} 

任何人都可以幫助我嗎? Thanls

+4

不是一個直接的答案,但請,請學習和**使用** paramterized查詢,**尤其是**,因爲你正在開發一個Web應用程序。你的代碼是SQL Server注入的開放源代碼。 – Tim

+0

爲了更直接地回答您的問題,我會使用存儲過程來執行插入操作。 SP將檢查一個現有的ID,如果它發現一個返回的東西指示ID已經存在,否則它會完成插入。 – Tim

+0

@Tim我已經多次聽到同樣的事情,你可以請寫參數化查詢相同的查詢,以便我可以理解如何使用它? – yrazlik

回答

0

我所做的電子郵件屬性作爲主鍵,然後檢查了數據庫相同的電子郵件是否存在,以及工作

+0

這與原始問題有什麼關係?以這種方式修改主鍵是一筆巨大的交易。我不明白你的解決方案。 – OzrenTkalcecKrznaric

0

與嘗試添加具有相同ID的用戶返回的錯誤不同,最好首先檢查用戶的存在,如果可以,則只創建新帳戶。儘管你仍然需要處理這個例外,以迎合兩個人試圖創建相同記錄的情況。

所以你有以下SQL:

select * from StudentTable where ID = @newID 

,如果此發現了一個記錄,你可以報告錯誤。如果它找不到任何東西,那麼你可以繼續創建新的記錄。

雖然如果您使用該ID作爲主鍵,那麼最好將它作爲表上的Identity列,並在創建新行時使其自動遞增。您仍然必須檢查該學生是否已經存在 - 將該電子郵件用作人類可讀的唯一性條件。

如果您在電子郵件列上添加唯一性約束,那麼您將能夠捕獲兩個人嘗試創建相同記錄的情況。

+0

這忽略了併發性。另一個用戶可以在選擇之後,但在插入之前創建相同的ID。插入異常應該在任何情況下處理,即使選擇完成以獲得更好的用戶體驗。 –

+0

@BrankoDimitrijevic - 的確如此。 – ChrisF

1

有多種方法。您可以捕獲異常並顯示錯誤消息。這也有助於解決其他錯誤情況,例如丟失連接。

但是,如果這是您希望在正常操作期間發生的情況,那麼您應該在沒有例外的情況下處理這種情況。要做到這一點的方法之一是讓你的insert只能插入一排新的id

insert YourTable 
     (id, col1, col2, ...) 
select @id 
,  @col1 
,  @col2 
,  ... 
where not exists 
     (
     select * 
     from YourTable 
     where id = @id 
     ) 

參數傳遞到您的查詢,如:

command.Parameters.AddWithValue("@id", 42); 
command.Parameters.AddWithValue("@col1", "value1"); 
command.Parameters.AddWithValue("@col2", "value2"); 

現在ExecuteNonQuery()返回受影響的行數。你可以用它來檢查,如果insert實際上增加了一個新的行表:

var result = command.ExecuteNonQuery(); 
if (result == 1) 
{ 
    lblResult.Text = "New row inserted!"; 
    lblResult.Color = Color.Green; 
} 
else 
{ 
    lblResult.Text = "Failed to insert new row."; 
    lblResult.Color = Color.Red; 
} 
+0

謝謝,但我是新來的asp.net,不知道如何使用參數化查詢,所以我有一個關於你的答案的問題:是插入...哪裏不存在...聲明一個字符串變量? – yrazlik

+0

是的,你可以在'command.CommandText'中將該查詢存儲爲一個字符串。 '@ varname'是參數,除其他外,它將保護您免受SQL注入 – Andomar