2011-09-07 65 views
1

如果您請幫我解決問題,我正嘗試使用所有4個鍵(Role_ID, Track_ID, Person_ID, Conference_ID)上的唯一約束來更新表。具有唯一約束條件的SQL更新命令asp.net

爲什麼我不能更新它?

錯誤:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: Violation of UNIQUE KEY constraint 'UK_conferenceRole'. Cannot insert duplicate key in object 'dbo.ConferenceRole'. The statement has been terminated.

代碼:

var sqlCon7 = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString); 
string query7 = @"update ConferenceRole set Role_ID =" + 3 + ",Person_ID='" + idp + "'where Conference_ID ='" + conference + "'and Track_ID='" + TrackId + "'"; 

SqlCommand cmd7 = new SqlCommand(query7, sqlCon7); 
cmd7.CommandType = CommandType.Text; 

try 
{ 
    sqlCon7.Open(); 
    cmd7.ExecuteNonQuery(); 
    sqlCon7.Close(); 
} 
catch (Exception ee) 
{ 
    throw ee; 
} 

在此先感謝

+1

首先,請停止直接使用ADO.NET ,至少使用像這樣的庫http://abstractsql.codeplex.com – BlackTigerX

+2

請,請停止使用字符串連接來建立SQL查詢!你已經使用了一個SqlCommand對象,所以也使用參數! –

回答

2

您的代碼應該看起來像這樣 - 通過所有方法,避免只需將你的SQL語句串起來!(這是SQL注入的開門人!)。此外,使用ADO.NET,你應該把你的連接和命令到使用塊,以確保不再需要時,他們得到妥善處置:

// define/read connection string and SQL statement 
string connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; 
string sqlStatement = "UPDATE ConferenceRole SET Role_ID = @RoleID, " + 
         "Person_ID = @PersonID, " + 
         "WHERE Conference_ID = @ConferenceID AND Track_ID = @TrackID"; 

// put your SqlConnection and SqlCommand into using blocks! 
using(SqlConnection _con = new SqlConnection(connectionString)) 
using(SqlCommand _cmd = new SqlCommand(sqlStatement, _con)) 
{ 
    // define and set parameter values 
    _cmd.Parameters.Add("@RoleID", SqlDbType.INT).Value = 3; 
    _cmd.Parameters.Add("@PersonID", SqlDbType.INT).Value = idp; 
    _cmd.Parameters.Add("@ConferenceID", SqlDbType.INT).Value = conference; 
    _cmd.Parameters.Add("@TrackID", SqlDbType.INT).Value = trackId; 

    // execute query 
    _con.Open(); 
    _cmd.ExecuteNonQuery(); 
    _con.Close(); 
} 

而且這個結構在這裏:

catch (Exception ee) 
{ 
    throw ee; 
} 

是絕對毫無意義 - 它所做的就是破壞調用堆棧,例如你將無法看到異常真正從了出來 - 就這麼走了出來一起,或者如果你必須 - 使用

catch (Exception ee) 
{ 
    throw; // **DO NOT** specify the 'ee' exception object here! 
} 

什麼錯誤說,你想創建一個副本進入表 - 一個組合(Role_ID, Track_ID, Person_ID, Conference_ID)已經存在。這就是獨特約束的要點:防止這種情況發生。因此,請檢查您的表格 - 您的表格中必須已經有與您嘗試更新此行的值相同的四個值。

1

您定義Role_ID和/或Person_ID在你的表的主鍵,已經有與記錄相同的值和記錄是不是conferenceTrack_ID你正在通過參數

另外你的SQL語句很容易出現SQL注入攻擊。最好是參數化你的查詢。

0

您必須查看數據庫中關於該約束的定義,它會告訴您要查找哪些列(如果您擁有Sql Management Studio或類似的東西),請打開數據庫,展開該表並查看約束,右鍵單擊並查看UK_conferenceRole約束的定義,如果您更新問題並在此處發帖,則會更容易幫助您