IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Windows Forms Discussion :

Utilisation de parametres pour les requêtes SQL


Sujet :

Windows Forms

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 22
    Par défaut Utilisation de parametres pour les requêtes SQL
    Bonjour, j'aurai voulu avoir quelques renseignements sur l'utilisation de paramètres lors de l'exécution d'une requête sql INSERT INTO
    Voila mon problème
    Je veux enregistrer une personne dans ma table et récupérer l'ID générer automatiquement. J'utilise des paramètres (j'ai lu que c'était plus sécurisé) mais ma requête ne passe pas
    Voici le code associé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    
    //Declaration globale
            private const string PARM_Nom = "@Nom";
            private const string PARM_Prenom = "@Prenom";
            ...
    object[] ICandidat.AddCandidat(CandidatInfo Candidat)
    {
            //Corps de la methode
             string SqlAdd = "INSERT INTO Personne (Nom, Prenom, ... ";
             SqlAdd = SqlAdd + VALUES(@Nom, @Prenom,...";
             SqlAdd = SqlAdd + "); SELECT @@IDENTITY;";
    
    SqlParameter[] parms {	   
            new SqlParameter(PARM_Nom, SqlDbType.VarChar),
            new SqlParameter(PARM_Prenom, SqlDbType.VarChar),
            ...
    };
            parms[0].Value = Candidat.NomFr;
            parms[1].Value = Candidat.PrenomFr;
            ...
            SqlConnection conn = new SqlConnection(SqlHelper.ConnectionString);
            conn.Open();
            SqlTransaction trans = conn.BeginTransaction(IsolationLevel.ReadCommitted);
            object ID;
            object[] Resultat = new object[2];
    
            try
            {
                 ID = SqlHelper.ExecuteScalar(trans, CommandType.Text, SqlAdd,parms);
                 trans.Commit();
                 Resultat[0] = bool.Parse("true");
                 Resultat[1] = int.Parse(ID.ToString());
                 return Resultat;
            }
            catch
            {
                 trans.Rollback();
                 Resultat[0] = bool.Parse("false");
                 Resultat[1] = int.Parse("0");
                 return Resultat;
            }
            finally
            {
                 conn.Close();
            }
    }
    
    public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    {
            if (transaction == null) throw new ArgumentNullException("transaction");
                if (transaction != null && transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
    
            // Create a command and prepare it for execution
            SqlCommand cmd = new SqlCommand();
            bool mustCloseConnection = false;
            PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection);
    
            // Execute the command & return the results
            object retval = cmd.ExecuteScalar();
    
            // Detach the SqlParameters from the command object, so they can be used again
            cmd.Parameters.Clear();
            return retval;
    }
    
    private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection)
    {
            if (command == null) throw new ArgumentNullException("command");
            if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");
    
            // If the provided connection is not open, we will open it
            if (connection.State != ConnectionState.Open)
            {
                 mustCloseConnection = true;
                 connection.Open();
            }
            else
            {
                 mustCloseConnection = false;
            }
    
            // Associate the connection with the command
            command.Connection = connection;
    
            // Set the command text (stored procedure name or SQL statement)
            command.CommandText = commandText;
    
            // If we were provided a transaction, assign it
            if (transaction != null)
            {
                 if (transaction.Connection == null) throw new ArgumentException("The transaction was rollbacked or commited, please provide an open transaction.", "transaction");
                    command.Transaction = transaction;
            }
    
            // Set the command type
            command.CommandType = commandType;
    
            // Attach the command parameters if they are provided
            if (commandParameters != null)
            {
                 AttachParameters(command, commandParameters);
            }
            return;
    }
    La ligne en gras est apparemment celle qui plante
    Donc voici les questions
    - Quand est ce que les paramètre sont insérer dans la requête? Est ce justement au sein de la méthode ExecuteScalar()?
    Car lors du debuggage, si je regarde les propriétés de l'objet cmd, les paramètres sont encore dans la requête et non les valeurs.
    - Est vraiment plus sécurisé d'utiliser des paramètres plutôt que de passer les valeurs directement dans la requête?
    - Lors de la déclaration des constantes, le type doit il obligatoirement être un string même si l'enregistrement en base de donnée est un int ou une date?

    J'avoue être un peu perdu avec l'utilisation des paramètres
    Je précise que je reprend le code d'une personne avant moi que je ne peut contacter

    SI une âme charitable veux bien m'aider, merci d'avance

  2. #2
    Membre confirmé Avatar de Saten
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 203
    Par défaut
    Oui utiliser les requêtes paramétrées est plus sécurisé, mais attention c'est pas "j'utilise les paramètres, donc mon appli est invulnérable.".

    Pour utiliser les requetes SQL paramétrées voilà un exemple simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
                //Paramètres de connexion
                Connect();
    
                //Définition des SQLParameters
                MySqlParameter param_nom = new MySqlParameter("@nom", MySqlDbType.String, 50);
                //On associe à la variable récupérée précédemment
                param_nom.Value = [une_valeur];
    
                //On recommence pour autant de paramètres qu'on veut
    
                //On définit la requête SQL
                String sql = string.Format("INSERT INTO ***(NOM, ***) VALUES({0},***)", param_nom.ParameterName);
                MySqlCommand cmd = new MySqlCommand(sql.ToString(), Connection);
                //On ajoute les paramètres définis à la commande SQL
                cmd.Parameters.Add(param_nom);
    
                 try
                {
                    Connection.Open();
                    //Exécution requête
                    cmd.ExecuteNonQuery();
                   Connection.Close();
                }
    
                catch
                {
                    // Si la connexion a échoué, message d'erreur                
                    Connection.Close();
                }
    EDIT : c'est pas la méthode avec executeScalar, mais NonQuery, mais bon, le principe y est .

  3. #3
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 22
    Par défaut
    En fait j'utilise ExecuteScalar car je veux recupérer l'ID créer car j'en ai besoin pour la suite et que c'est un peu plus propre que de refaire une requête

    Et quand je fais ça ça revient au même que ta chaine d'insertion?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
             string SqlAdd = "INSERT INTO Personne (Nom, Prenom, ... ";
             SqlAdd = SqlAdd + VALUES(@Nom, @Prenom,...";
    PS : Bon je viens de m'apercevoir que j'ai oublié la méthode qui construit la commande sql, j'edit mon premier message

  4. #4
    Membre confirmé Avatar de Saten
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 203
    Par défaut
    C'est pas ça, regarde ici les différences entre les types d'éxécution de requêtes : (c'est en anglais sorry)

    Ce que tu veux faire est mieux avec execute non query...pas besoin de executescalar là...

  5. #5
    Membre averti
    Inscrit en
    Novembre 2008
    Messages
    22
    Détails du profil
    Informations forums :
    Inscription : Novembre 2008
    Messages : 22
    Par défaut
    Ok donc je vais tester avec ExecuteNonQuery
    Et pour les autres questions?


    Apres test le NonQuery ne fonctionne pas non plus
    Voici le code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
            public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
                SqlCommand cmd = new SqlCommand();
                PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
    Toujours une erreur lors de l'exécution de la requête
    Il doit y avoir une erreur ailleurs mais j'arrive pas a identifier ou

  6. #6
    Membre confirmé Avatar de Saten
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 203
    Par défaut
    Alors dans l'ordre :

    • - Quand est ce que les paramètre sont insérer dans la requête? Est ce justement au sein de la méthode ExecuteScalar()?
      Car lors du debuggage, si je regarde les propriétés de l'objet cmd, les paramètres sont encore dans la requête et non les valeurs.
      Réponse dans mon code; D'abord tu crée ton paramètre, tu lui assigne une valeur, tu insère dans ta string de requete au lieu des valeurs des {0}, {1}, etc. à la fin de ta requête tu met une virgule, puis dans l'ordre tu associe les paramètre (le premier sera associé à {0}, etc.). Enfin apres ta commande de requete tu ajoute tes paramètres. finalement tu exécute! (tout est dans le code que je t'ai donné)
    • - Est vraiment plus sécurisé d'utiliser des paramètres plutôt que de passer les valeurs directement dans la requête?
      OUI! Il existe des attaques dites "d'injection SQL" où les champs (textboxs, etc.) sont utilisées pour injecter des requetes pirates qui affecteraient ta base, là pas de rique là dessus. Après c'est plus rapide car compiler avec le code. Pour de plus ample infos, voilà un super lien :
    • - Lors de la déclaration des constantes, le type doit il obligatoirement être un string même si l'enregistrement en base de donnée est un int ou une date?
      Généralement oui, du moment que tu as une seule string, et puis ça mange pas de pain!
      Après tu doit paramétrer tes paramètres (elle est belle celle-là ), et définir le type de données de ton paramètre:

      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
       
      MySqlParameter param_prix = new MySqlParameter("@prix", MySqlDbType.Double);
                  paramprix.Value = variable_du_prix;


    Voilà, j'ai répondu à tout?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. La masque de saisie pour les requêtes SQL
    Par Glauben dans le forum Général Java
    Réponses: 0
    Dernier message: 31/05/2011, 23h49
  2. Réponses: 6
    Dernier message: 14/12/2007, 23h26
  3. [SQL-SEVER2005] Gestion des erreurs pour les requêtes
    Par eagleleader dans le forum MS SQL Server
    Réponses: 22
    Dernier message: 16/10/2007, 09h59
  4. Réponses: 2
    Dernier message: 28/02/2007, 13h13
  5. [SQL] Sprintf ou concaténation pour créer les requêtes SQL?
    Par EvilAngel dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 15/09/2006, 17h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo