2010-05-29 86 views
1

首先,請幫助我!我再也受不了了。我找不到錯誤的位置。這是我的問題:通過C#Winform應用程序更新語句更新0行?

我想通過C#winform應用程序更新一行。從應用程序生成的更新查詢格式正確。我在sql server環境中測試過它,它運行良好。當我從應用程序運行它時,我得到0行更新。

下面是使用反射生成更新語句的代碼片段 - 不要試圖弄清楚它。進行代碼部分之後讀:下面

 public void Update(int cusID) 
     { 
      SqlCommand objSqlCommand = new SqlCommand(); 
      Customer cust = new Customer(); 

      string SQL = null; 

      try 
      { 
       if ((cusID != 0)) 
       { 
         foreach (PropertyInfo PropertyItem in this.GetType().GetProperties()) 
         { 
          if (!(PropertyItem.Name.ToString() == cust.PKName)) 
          { 
           if (PropertyItem.Name.ToString() != "TableName") 
           { 
            if (SQL == null) 
            { 
             SQL = PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString(); 
            } 
            else 
            { 
             SQL = SQL + ", " + PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString(); 
            } 
           } 
           else 
           { 
            break; 
           } 
          } 
         } 

         objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + "'" + "@phNum" + "'"; 

         foreach (PropertyInfo PropertyItem in this.GetType().GetProperties()) 
         { 
          if (!(PropertyItem.Name.ToString() == cust.PKName)) 
          { 
           if (PropertyItem.Name.ToString() != "TableName") 
           { 
            objSqlCommand.Parameters.AddWithValue("@" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null)); 
           } 
           else 
           { 
            break; 
           } 

          } 
         } 

         objSqlCommand.Parameters.AddWithValue("@cusID", cusID); 
         objSqlCommand.Parameters.AddWithValue("@phNum", this.PhoneNumber); 
         DAL.ExecuteSQL(objSqlCommand); 
       } 
       else 
       { 
        //AppEventLog.AddWarning("Primary Key is not provided for Update.") 
       } 

      } 
      catch (Exception ex) 
      { 
       //AppEventLog.AddError(ex.Message.ToString) 
      } 
     } 

這部分:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + "'" + "@phNum" + "'"; 

生成DML:

UPDATE CustomerPhone SET PhoneTypeID = @PhoneTypeID, PhoneNumber = @PhoneNumber WHERE CustomerID = @cusID AND PhoneNumber = '@phNum' 

@PhoneTypeID和@PhoneNumber從兩個特性得到。我們從用戶輸入文本框中將值分配給表示層中的這些屬性。下面,說明由部分獲取的值:

objSqlCommand.Parameters.AddWithValue("@" + PropertyItem.Name.ToString(), PropertyItem.GetValue(this, null)); 

下面的代碼填充的WHERE的值:

    objSqlCommand.Parameters.AddWithValue("@cusID", cusID); 
        objSqlCommand.Parameters.AddWithValue("@phNum", this.PhoneNumber); 

最後的代碼應看:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = 999444 
WHERE CustomerID = 500 AND PhoneNumber = '911'; 

手機類型ID是7 - 從文本框取得的用戶值 電話號碼爲999444 - 取自文本框的用戶值

上述最終更新語句適用於sql環境,但通過應用程序運行 時,execute非查詢運行正常,並獲得0行更新!我想知道爲什麼?

回答

3

這就是問題所在:

AND PhoneNumber = '@phNum' 

這是尋找一個電話號碼這正是文字'@phNum' - 這是而不是使用一個名爲phNum的參數。你想

AND PhoneNumber = @phNum 

你也打破你的字符串字面量沒有明顯的理由。本聲明:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + 
    " WHERE " + cust.PKName + " = @cusID AND PhoneNumber = " + 
    "'" + "@phNum" + "'"; 

會更容易閱讀爲:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + 
    " WHERE " cust.PKName + " = @cusID AND PhoneNumber = '@phNum'"; 

顯然,你想從它刪除單引號,使它只是:

objSqlCommand.CommandText = "UPDATE " + this.TableName + " SET " + SQL + 
    " WHERE " cust.PKName + " = @cusID AND PhoneNumber = @phNum"; 

小的重構也不會出錯。這個循環:

foreach (PropertyInfo PropertyItem in this.GetType().GetProperties()) 
{ 
    if (!(PropertyItem.Name.ToString() == cust.PKName)) 
    { 
     if (PropertyItem.Name.ToString() != "TableName") 
     { 
      if (SQL == null) 
      { 
       SQL = PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString(); 
      } 
      else 
      { 
       SQL = SQL + ", " + PropertyItem.Name.ToString() + " = @" + PropertyItem.Name.ToString(); 
      } 
     } 
     else 
     { 
      break; 
     } 
    } 

}

會更簡單,更具可讀性像這樣:

StringBuilder sqlBuilder = new StringBuilder(); 
foreach (PropertyInfo property in this.GetType().GetProperties()) 
{ 
    string name = property.Name; 
    // I believe you had a bug before - the properties being updated 
    // would depend on the ordering of the properties - if it 
    // ran into "TableName" first, it would exit early! 
    // I *suspect* this is what you want 
    if (name != cust.PKName && name != "TableName") 
    { 
     sqlBuilder.AppendFormat("{0} = @{0}, ", name); 
    } 
} 
// Remove the trailing ", " 
if (sqlBuilder.Length > 0) 
{ 
    sqlBuilder.Length -= 2; 
} 

你可以做最後的循環過類似的東西。

+0

我會檢查你的解決方案,順便說一下電話號碼是串....我會回來 – peace 2010-05-29 10:43:05

+0

我得到一個錯誤,指出:
UPDATE語句衝突與外鍵約束...
我試圖更新的表有兩個fk的列和一個常規列。沒有主鍵。 – peace 2010-05-29 12:39:45

+0

CustomerID和PhoneTypeID是fk的 – peace 2010-05-29 12:40:11

2

PhoneNumber一個字符串,還是一個整數?

我看你SET是一個整數,但檢查WHERE作爲一個文字。難道這不是問題嗎?

如果它是一個整數,嘗試:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = 999444 
WHERE CustomerID = 500 AND PhoneNumber = 911; 

如果它是一個字符串,請嘗試:

UPDATE CustomerPhone 
SET PhoneTypeID = 7, PhoneNumber = '999444' 
WHERE CustomerID = 500 AND PhoneNumber = '911';