2010-05-29 3 views
1

Tout d'abord, s'il vous plaît aidez-moi! Je ne peux plus supporter cela. Je n'ai pas pu trouver l'emplacement de l'erreur. Voici mon problème:Mises à jour des instructions de mise à jour 0 lignes via l'application C# Winform?

J'essaie de mettre à jour une ligne via une application winform C#. La requête de mise à jour générée à partir de l'application est formatée correctement. Je l'ai testé dans l'environnement du serveur sql, ça a bien marché. Quand je l'exécute à partir de l'application, je reçois 0 lignes mises à jour.

Voici l'extrait qui génère l'instruction de mise à jour en utilisant la réflexion - ne tentez pas de le comprendre. Effectuer la lecture après que la partie de code:

 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) 
      } 
     } 

Cette partie ci-dessous:

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

génère DML:

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

@PhoneTypeID et @PhoneNumber sont obtenus à partir de deux propriétés. Nous avons attribué la valeur à ces propriétés dans la couche de présentation à partir de la zone de texte de saisie utilisateur. La partie ci-dessous où va chercher les valeurs:

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

Le code ci-dessous remplit les valeurs de OÙ:

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

Le code final devrait ressembler:

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

Téléphone type id est 7 - la valeur d'utilisateur qui est prise de la zone de texte Numéro de téléphone est 999444 - valeur d'utilisateur qui est prise de la zone de texte

L'instruction de mise à jour finale ci-dessus fonctionne sur l'environnement sql, mais lors de l'exécution de via l'application, l'exécution de non-exécution s'exécute correctement et obtient 0 lignes mises à jour! Je me demande pourquoi?

Répondre

3

C'est le problème:

AND PhoneNumber = '@phNum' 

qui cherche un numéro de téléphone qui est exactement le texte '@phNum' - c'est pas en utilisant un paramètre appelé phNum. Vous voulez

AND PhoneNumber = @phNum 

Vous enfreignez également vos chaînes littérales sans raison évidente.Cette déclaration:

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

serait plus facile à lire comme:

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

Il est évident que vous voulez déposer les apostrophes de celui-ci, pour le rendre juste:

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

Un peu refactoring ne serait pas mal non plus. Cette boucle:

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; 
     } 
    } 

}

serait plus simple et plus facile à lire comme ceci:

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; 
} 

Vous pouvez faire quelque chose de similaire avec la boucle finale aussi.

+0

Je vais vérifier vos solutions, par le numéro de téléphone de façon est une chaîne .... Je serai de retour – peace

+0

je reçois une erreur qui dit:
L'instruction UPDATE en conflit avec la contrainte FOREIGN KEY ...
La table que j'essaye de mettre à jour a deux colonnes de fk et une colonne régulière. Aucune clé primaire. – peace

+0

CustomerID et PhoneTypeID sont les fk – peace

2

Est-ce que PhoneNumber est une chaîne ou un nombre entier?

Je vois que vous êtes SET ting comme un entier, mais en vérifiant le WHERE comme un littéral. Cela ne pourrait-il pas être le problème?

Si c'est un entier, essayez:

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

Si c'est une chaîne, essayez:

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