2013-08-06 5 views
0

J'ai une instruction SQL Update qui, lorsqu'elle est exécutée dans VS2010 via la nouvelle fenêtre de requête, fonctionne, mais lorsque je la structure comme une instruction de mise à jour, rien ne se passe. Je me demandais si quelqu'un peut voir ce que je fais mal? Comme je l'ai dit, le code fonctionne lorsqu'il est exécuté via la fenêtre de requête dans VS2010.Instruction de mise à jour SQL ne fait rien

Voici mon code:

SqlConnection connection = new SqlConnection(DBConnection.GetConnection().ConnectionString); 

string updateStatement = 
    "DECLARE @OldParent hierarchyid, @NewParent hierarchyid " + 

    "SELECT @OldParent = Hierarchy FROM SpecProducts " + 
    "WHERE ID = @NodeToMoveID ; ------ top item to be moved " + 

    "SELECT @NewParent = Hierarchy FROM SpecProducts " + 
    "WHERE ID = @NodeToMoveIntoID ; -- ID of item to move into - new parent " + 

    "DECLARE children_cursor CURSOR FOR " + 
    "SELECT Hierarchy FROM SpecProducts " + 
    "WHERE Hierarchy = @OldParent; " + 

    "DECLARE @ChildId hierarchyid; " + 
    "OPEN children_cursor " + 

    "FETCH NEXT FROM children_cursor INTO @ChildId; " + 

    "WHILE @@FETCH_STATUS = 0 " + 
    "BEGIN " + 
    "START: " + 

     "DECLARE @NewId hierarchyid; " + 
     "SELECT @NewId = @NewParent.GetDescendant(MAX(Hierarchy), NULL) " + 
     "FROM SpecProducts WHERE Hierarchy.GetAncestor(1) = @NewParent; " + 

     "UPDATE SpecProducts " + 
     "SET Hierarchy = Hierarchy.GetReparentedValue(@ChildId, @NewId), " + 
      "MovedToDate = @MovedToDate, " + 
      "MovedToBy = @MovedToBy " + 
     "WHERE Hierarchy.IsDescendantOf(@ChildId) = 1; " + 

     "IF @@error <> 0 GOTO START -- On error, retry " + 
     "FETCH NEXT FROM children_cursor INTO @ChildId; " + 
     "END " + 

     "CLOSE children_cursor; " + 
     "DEALLOCATE children_cursor;"; 

SqlCommand updateCommand = new SqlCommand(updateStatement, connection); 
updateCommand.Parameters.AddWithValue("@NodeToMoveID", nodeIDToMove); 
updateCommand.Parameters.AddWithValue("@NodeToMoveIntoID", newParentID); 
updateCommand.Parameters.AddWithValue("@MovedToDate", DateTime.Now); 
updateCommand.Parameters.AddWithValue("@MovedToBy", userModifying.ID); 

try 
{ 
    connection.Open(); 
    updateCommand.ExecuteNonQuery(); 

    return true; 
} 

Une chose à signaler est que lorsque mon code exécute dans la fenêtre VS2010 requête, je reçois un avertissement au sujet de la « déclarer » caractéristique, mais je presse continue et il fonctionne. Est-ce que ma déclaration qui ne fonctionne pas a quelque chose à voir avec les fonctionnalités de Declare?

Toutes pensées/solutions seraient grandement appréciées.

Merci beaucoup.

Rob

+1

Note secondaire: vous devez ** fermer ** votre connexion juste après l'exécution de la requête ... –

+1

Au lieu de coder en dur ces instructions sql, pourquoi ne pas le transformer en procédure stockée? – unlimit

+0

Si vous mettez un point d'arrêt à 'SqlCommand updateCommand = new SqlCommand (updateStatement, connection);' et obtenez la valeur de 'updateStatement', exécutez ceci dans la fenêtre de requête, cela fonctionne? – christiandev

Répondre

1

J'ajoute cela comme une réponse depuis la discussion de commentaires était un peu longue.

Selon le documentation, ExecuteNonQuery renvoie -1 lorsqu'il y a une annulation de base de données. Ceci est probablement lié à l'erreur que vous avez donné:

Source d'erreur: fournisseur de données .net.sqlclient
message d'erreur: doit déclarer le variabe scalaire NodeToMoveID & NodeToMoveIntoID & MovedToDate.

Comme vous l'avez mentionné, vous rencontriez des problèmes lors de l'utilisation des paramètres SQL. Une solution à ceci est de remplacer ces paramètres par des variables dans updateStatement.

Une autre chose que vous pouvez essayer est d'utiliser une procédure stockée et de modifier ces paramètres, bien que cela puisse ne pas fonctionner pour une raison quelconque.