2013-05-14 4 views
1

je suivais cette réponse,Quelqu'un peut-il me dire pourquoi cette requête SQL ne fonctionne pas

How can I supply a List<int> to a SQL parameter?

S'il vous plaît voir ces de mes questions pour le scénario comprendre,

How can I update Crate IDs of List of Fruits in single SQL query in c#

how can i update SQL table logic

Ce que j'essaie et ne fonctionne pas

private void relate_fruit_crate(List<string> selectedFruitIDs, int selectedCrateID) 
{ 
    string updateStatement = "UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID = @selectedFruitIDs"; 

    using (SqlConnection connection = new SqlConnection(ConnectionString())) 
    using (SqlCommand cmd = new SqlCommand(updateStatement, connection)) 
    { 
     connection.Open(); 
     cmd.Parameters.Add(new SqlParameter("@selectedCrateID", selectedCrateID.ToString())); 
     cmd.Parameters.Add(new SqlParameter("@selectedFruitIDs", String.Join(",",selectedFruitIDs.ToArray()))); 

     cmd.ExecuteNonQuery(); 
    } 
} 

Mon code fonctionne sans erreur,

+0

définissent "ne fonctionne pas". Les données ne sont pas mises à jour dans la base de données? Essayez-vous de courir dans le serveur SQL directement? – Raptor

+0

S'il vous plaît lire http://meta.stackexchange.com/questions/10647/how-do-i-write-a-good-title –

Répondre

4

Vous devez utiliser le mot-clé IN dans votre scénario. Le problème est que le modèle SqlCommand.Parameters ne construit pas la requête elle-même, mais appelle une procédure stockée sur la base de données:

exec sp_executesql N'UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID in(''@selectedFruitIDs'')', N'@selectedCrateID nvarchar(1),@selectedFruitIDs nvarchar(5)', @selectedCrateID = N'1', @selectedFruitIDs = N'1,2' 

Cela ne fonctionnera pas que le tableau est échappé.

La solution de contournement consiste à utiliser un StringBuilder normal pour créer la requête. (Avertissement! Injection SQL) ou pour appeler la requête pour chaque ID séparément.

Peut-être y at-il un moyen de le faire avec le SqlCommand.Parameters, mais je ne pouvais pas en trouver un.

VIEUX POST ::

string updateStatement = "UPDATE relate_fruit_crate set CrateID IN ('@selectedCrateID') where FruitID = '@selectedFruitIDs'"; 

[....]

cmd.Parameters.Add(new SqlParameter("@selectedFruitIDs", String.Join("','",selectedFruitIDs.ToArray()))); 

et égal (=) requête ne correspond une seule valeur.

+0

+1, Comme c'est étrange mais ça ne fonctionne toujours pas – Mathematics

+0

Oui, il doit être 'In' au lieu de '=', mais le paramètre sera toujours juste une valeur de chaîne concaténée. – juharr

+0

cela fonctionne uniquement si vos ID sont numériques. Vous devez ajouter des guillemets simples à chaque valeur comme le signale [juharr] (http: // stackoverflow.com/questions/16540951/can-someone-say-me-pourquoi-this-sql-query-not-working/16541024 # comment23757338_16541108) – krizzzn

1

Les requêtes de paramètres à plusieurs valeurs sont un peu pénibles dans TSQL. Il y a des options comme les paramètres de table, ou les "UDF" divisées - sinon ... c'est un peu compliqué. Vous finissez par devoir ajouter plusieurs paramètres (en fonction des données) et modifier la requête en conséquence. Si je peux suggérer ... une bibliothèque comme « pimpant » peut vous aider ici - il est conçu pour faire des scénarios comme celui-ci facile:

using Dapper; // at the top of your code file, to enable dapper 
... 
private void relate_fruit_crate(List<string> selectedFruitIDs, int selectedCrateID) 
{ 
    // note the slightly unusual "in" here (no paranethesis) - that is because 
    // dapper is going to do some voodoo...  
    using (SqlConnection connection = new SqlConnection(ConnectionString())) 
    { 
     connection.Open(); 
     connection.Execute(
      "UPDATE relate_fruit_crate set CrateID = @selectedCrateID where FruitID in @selectedFruitIDs", 
      new { selectedFruitIDs, selectedCrateID }); 
    } 
} 

ici « pimpant » fait tout le travail de trouver comment exprimer que in en utilisant plusieurs paramètres, en ajoutant le nombre correct de paramètres. C'est aussi beaucoup plus facile (en particulier, regardez le peu de travail que nous avons fait avec les commandes et les paramètres, il gère aussi bien les lecteurs).

Dapper est freely available from NuGet

Questions connexes