2009-02-24 10 views
1

J'ai ce formulaire Web C# qui a une boîte de sélection de date. Si la date est définie sur Nothing (valeur par défaut), je souhaite qu'elle transmette NULL à la base de données. Cela se produit dans ma requête paramétrée.Mon paramètre SQLParameter ne transmet pas correctement la valeur NULL

SqlParameter CMActionDate = new SqlParameter(); 
CMActionDate.ParameterName = "@ActionDate"; 
if (ActionDate.Equals("")) 
    { 
     CMActionDate.Value = System.Data.SqlTypes.SqlDateTime.Null; 
    } 
    else 
    { 
     CMActionDate.Value = ActionDate; 
    } 

Quand je tourne le débogage je vois que la date est en effet « » il va dans l'instruction IF et définit la actiondate.value à {NULL} comme je pense qu'il devrait.

Cependant.

Quand il va alors exécuter le nonquery, je clique sur la loupe et voir ceci:

UPDATE table SET [action_date] = '' WHERE [id] = 2488 

Ce que je voudrais voir est la suivante:

UPDATE table SET [action_date] = 'Null' WHERE [id] = 2488 

Depuis le action_date jamais vraiment obtient la valeur NULL, puis la valeur dans le champ datetime redevient "01/01/1900 12:00:00 AM" et c'est une douleur en soi.

J'ai essayé d'installer CMActionDate.Value aux valeurs suivantes en vain (je reçois le même résultat que ci-dessus.):

  • DBNull.Value;
  • "NULL";
  • SqlDateTime.Null;
  • null;

Aide.

EDIT

Peut-être que je n'étais pas clair? Oui, bien sûr, la requête paramétrisé ressemble à ceci:

"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' WHERE [id] = " + @CM_id + ""; 

Mais quand je suis débogage cette chose dans VS, je mets un point d'arrêt avant droit ExecuteNonQuery(); donc je peux voir le SQL qu'il essaie de lancer. C'est là que je vois le vrai SQL et vois le bit où action_date = ''.

Cela aide-t-il?

+0

Vous le faites mal. Lisez à nouveau le code dans ma réponse. Cela revient à essayer d'utiliser un paramètre comme une variable de substitution, et du point de vue du code C#, ce n'est pas le cas. –

+0

Notez que dans mon code, il n'y a pas de guillemets simples autour de @ActionDate et j'inclus @ActionDate dans la requête comme une autre partie de la chaîne littérale. –

Répondre

13

Vous ne devriez pas voir '' ou 'Null'. Si vous utilisez des requêtes paramétrées correctement, il devrait ressembler à ceci:

SET Table MISE À JOUR [action_date] = @ActionDate WHERE [id] = @ID

Le point entier d'un paramétrés requête est que la valeur réelle du paramètre est jamais substitué directement dans la chaîne de requête.

Votre code de requête devrait ressembler à ceci:

string sql = "UPDATE table SET [action_date]= @ActionDate WHERE [id]= @CM_id"; 

using (var cn = new SqlConnection("your connection string here.")) 
using (var cmd = new SqlCommand(sql, cn)) 
{ 
    cmd.Parameters.Add("@ActionDate", SqlDbTypes.DateTime).Value = 
     ActionDate.Equals("")? DBNull.Value : DateTime.Parse(ActionDate); 
    cmd.Parameters.Add("@CM_id", SqlDbTypes.Int).Value = 2488; 

    cn.Open(); 
    cmd.ExecuteNonQuery(); 
} 

Le résultat de ce code est que vos paramètres de requête sont envoyés au serveur en tant que données.À aucun moment dans votre code C#, vous ne pourrez voir la chaîne de requête avec vos données remplacées par: elle est envoyée séparément au serveur.

Cela empêche toute possibilité pour le serveur d'exécuter une valeur de paramètre en tant que code en raison d'une erreur d'assainissement de la valeur de votre paramètre. Les données sont complètement séparées et n'ont pas besoin d'être nettoyées pour ce contexte en premier lieu. Il permet également au serveur de mettre en cache et de réutiliser le plan d'exécution de la requête, ce qui entraîne une (petite) amélioration des performances.

+0

voir mon édition ci-dessus, je suppose que je n'étais pas assez clair. – somacore

+0

Cela l'a fait. Merci pour votre explication dans les commentaires ci-dessus. Cela m'a aidé à voir ce que je faisais de mal. Tout le monde est nouveau à quelque chose à un moment donné. – somacore

+0

Pas de soucis: juste pour que vous l'ayez à la fin :) –

1

Votre requête doit montrer paramétré

UPDATE table SET [action_date] = @ActionDate WHERE [id] = @id 

Et la valeur du paramètre doit avoir une valeur équivalente nulle.

Votre sql est

"UPDATE CM_Codebase SET [action_date] = '" + @ActionDate + "' 
WHERE [id] = " + @CM_id + ""; 

Ce qui ne fait pas vraiment de sens. Vous devez laisser sql remplacer @ActionDate et @CM_ID, ne pas créer une requête SQL dynamique.

Votre sql doit littéralement:

String sql = "UPDATE table SET [action_date] = @ActionDate WHERE [id] = @CM_id" 

Il ne faut pas concaténation de chaînes autour des variables et ils ne devraient pas être entre guillemets doubles.

+0

Pourquoi le -1? Ma réponse est la même que celle de Joel mais sans le code supplémentaire. – cjk

+0

J'ai upvoted ceci à 0 pour vous, mais voir ma modification ci-dessus pour la clarification. – somacore

+0

"Ma réponse est la même que celle de Joel mais sans le code supplémentaire" - Oui, et c'est précisément pourquoi j'ai voté contre votre réponse. –

0

Votre requête ne ressemble certainement pas à celle publiée.

Votre paramètre @ doit être dans votre chaîne pour être lu correctement. Vous voyez ActionDate = '' car @ActionDate n'existe pas, très probablement.

Vous avez besoin quelque chose comme

string sql = "UPDATE CM_Codebase SET [action_date] = @ActionDate WHERE [id] = @CM_id"; 

avis qu'il n'y a pas concaténation de chaîne en cours.

Questions connexes