[VB/SQLServeur] Problème Delete

Résolu
Bonjour,
J'ai un soucis depuis plusieurs jours avec mon programme fait sous VB 2008.

J'ai une listbox multiselection que je remplis avec des éléments d'une table d'une bdd SQL Serveur.
Puis j'ai un bouton supprimer ("button_1") qui supprime les éléments sélectionnés dans la listbox dans la bdd et qui raffraichit la listbox.

Mes soucis se trouvent dans la requête pour supprimer les éléments de la bdd.
Vous pouvez m'aider en me disant ce qu'il ne va pas...

Merci d'avance !

Je vous met mon code :

Imports System
Imports System.Data
Imports System.Data.SqlClient


Public Class Form1
    Dim Maconnexion As New SqlConnection
    Dim UnDataSet As New DataSet
    Dim UneDataTable As New DataTable
    Dim DeuxDataTable As New DataTable


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        Maconnexion.ConnectionString = "Data Source=.\SQLEXPRESS ; Integrated Security=SSPI; Initial Catalog=test"
        Dim Mycommand As SqlCommand = Maconnexion.CreateCommand()
        Mycommand.CommandText = "SELECT nom FROM client"
        Maconnexion.Open()
        Dim myReader As SqlDataReader = Mycommand.ExecuteReader()
        Do While myReader.Read()
            ListBox1.Items.Add(myReader.GetString(0))
        Loop
        myReader.Close()
    End Sub

    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

        Dim C As Integer = ListBox1.SelectedItems.Count
        While C <> 0
            Dim cmd As SqlCommand
            cmd = Maconnexion.CreateCommand
            cmd.CommandText = "DELETE FROM dbo.client WHERE nom = " & ListBox1.SelectedItem.ToString & " ; "
            MsgBox(cmd.CommandText)
            cmd.ExecuteNonQuery()
            C = C - 1
            Dim I As Integer = ListBox1.SelectedIndex
            'ListBox1.SelectedIndices.Remove(I)
            ListBox1.Items.RemoveAt(I)
        End While
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Maconnexion.Close()
        Me.Close()
    End Sub

End Class
Configuration: Windows XP
Firefox 3.0

10 réponses

  1. Webmaster
    Bonjour

    cmd.CommandText = "DELETE FROM dbo.client WHERE nom = " & ListBox1.SelectedItem.ToString & " ; "
    --> va générer une requête du genre : DELETE FROM dbo.client WHERE nom = toto
    --> Alors que la bonne requête est : DELETE FROM dbo.client WHERE nom = "toto"
    --> il faut que tu "enquotes" la chaine, soit à la main, soit avec une fonction VB qui doit b ien exister :)

    Bon courage
    1. J'ai finalement trouver je met mon code pour ceux qui cherche :

      Imports System
      Imports System.Data
      Imports System.Data.SqlClient
      
      Public Class suppression
          Dim Maconnexion As New SqlConnection()
          Dim UnDataSet As New DataSet()
          Dim UneDataTable As New DataTable()
      
          Private Sub suppression_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
      
              Maconnexion.ConnectionString = "Data Source=.\SQLEXPRESS ; Integrated Security=SSPI; Initial Catalog=test"
              Maconnexion.Open()
      
              Dim req1 As String
              req1 = "select * from dbo.client"
              Dim UnDataAdapter As New SqlDataAdapter(req1, Maconnexion)
              UnDataAdapter.Fill(UnDataSet, "client")
              UneDataTable = UnDataSet.Tables("client")
              ListBox1.DisplayMember = "nom"
              ListBox1.ValueMember = "id"
              ListBox1.DataSource = UneDataTable
              Dim X As Integer
              For X = 0 To ListBox1.Items.Count - 1
                  ListBox1.SetSelected(X, True)
              Next X
      
          End Sub
      
          Private Sub btn_Supp_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btn_Supp.Click
              Dim C As Integer = ListBox1.Items.Count
              For I As Integer = 0 To C - 1
                  If ListBox1.GetSelected(I) = True Then
                      Dim cmd As SqlCommand = Maconnexion.CreateCommand()
                      cmd.Connection = Maconnexion
                      cmd.CommandText = "DELETE FROM dbo.client WHERE id = " & ListBox1.SelectedValue
                      cmd.ExecuteNonQuery()
                      ListBox1.SelectedIndices.Remove(I)
                  End If
              Next I
      
              UneDataTable.Clear()
              ListBox1.DataSource = UneDataTable
      
              Dim req1 As String
              req1 = "select * from dbo.client"
              Dim UnDataAdapter As New SqlDataAdapter(req1, Maconnexion)
              UnDataAdapter.Fill(UnDataSet, "client")
              UneDataTable = UnDataSet.Tables("client")
              ListBox1.DisplayMember = "nom"
              ListBox1.ValueMember = "id"
              ListBox1.DataSource = UneDataTable
              Dim X As Integer
              For X = 0 To ListBox1.Items.Count - 1
                  ListBox1.SetSelected(X, True)
              Next X
          End Sub
      
          Private Sub btn_Quitter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Quitter.Click
              Maconnexion.Close()
              Me.Close()
          End Sub
      End Class
      1. Webmaster
        Bonjour,
        Je ne pense pas que ce code fasse ce que tu veux ...
         
               While C <> 0
                    Dim I As Integer = ListBox1.SelectedIndex
                    Dim cmd As SqlCommand = Maconnexion.CreateCommand()
                    cmd.Connection = Maconnexion
                    cmd.CommandText = "DELETE FROM dbo.client WHERE id = " & ListBox1.ValueMember
                    MsgBox(cmd.CommandText)
                    cmd.ExecuteNonQuery()
                    ListBox1.Items.RemoveAt(I)
                    C = C - 1
                End While
        

        Je rajouterais avant le end while un truc du genre ListBox1.SelectedIndex = C pour que la 1ère ligne de la boucle (Dim I as ...)
        De plus, tu dois pouvoir simplifier, je ne pense pas que C et I soient utiles, pour moi ils contiennent la meme chose non ?
        Je ne t'ecris pas le code parce que je ne connais que très peu VB :)
        1. Merci d'avoir essayer de m'aider... J'ai demandé de l'aide à quelqu'un de mon entourage et finalement y'a du progrès mais y'a toujours des problèmes...
          Maintenant la requête n'efface plus que le dernier enregistrement de ma table...

          Je met mon code au cas où cela inspire quelqu'un ^^
          Imports System
          Imports System.Data
          Imports System.Data.SqlClient
          
          Public Class Form1
              Dim Maconnexion As New SqlConnection()
              Dim UnDataSet As New DataSet()
              Dim UneDataTable As New DataTable()
          
          
              Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
          
                  Maconnexion.ConnectionString = "Data Source=.\SQLEXPRESS ; Integrated Security=SSPI; Initial Catalog=test"
                  Dim Mycommand As SqlCommand = Maconnexion.CreateCommand()
                  Mycommand.CommandText = "SELECT id, nom FROM client"
                  Maconnexion.Open()
                  Dim myReader As SqlDataReader = Mycommand.ExecuteReader()
                  Do While myReader.Read()
                      ListBox1.ValueMember = myReader.GetInt32(0)
                      ListBox1.Items.Add(myReader.GetString(1))
                  Loop
                  myReader.Close()
              End Sub
          
              Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
          
          
                  Dim C As Integer = ListBox1.SelectedItems.Count
                  MsgBox(C)
                  While C <> 0
                      Dim I As Integer = ListBox1.SelectedIndex
          
                      Dim cmd As SqlCommand = Maconnexion.CreateCommand()
                      cmd.Connection = Maconnexion
                      cmd.CommandText = "DELETE FROM dbo.client WHERE id = " & ListBox1.ValueMember
                      MsgBox(cmd.CommandText)
                      cmd.ExecuteNonQuery()
          
                      ListBox1.Items.RemoveAt(I)
          
                      C = C - 1
          
                  End While
              End Sub
          
              Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
                  Maconnexion.Close()
                  Me.Close()
              End Sub
          
          End Class
          1. Webmaster
            désolé mais je ne vois pas ... la requete SQL est correcte (si tu la copies/colles dans un client SQL, ca doit passer non ?) donc c'est un problème de code, et je ne connais pas .NET ...

            Il doit bien y avoir des experts ici ?

            Bon courage
            1. Cela ne marche toujours pas... Aurais-tu une autre solution a mettre à la place de mon code ?
              Parce que là j'y arrive pas du tout en je suis coincé depuis ce week-end !

              Merci d'avance
              1. Webmaster
                Je ne connais pas bien l'objet cmd.ExecuteNonQuery(), mais ca me parait tres bizarre ... essaie au cas ou les ' au lieu de " ?
                cmd.CommandText = "DELETE FROM dbo.client WHERE nom = "' & ListBox1.SelectedItem.ToString & '" ; "
                1. Déjà merci pour tes réponses, tu m'aides beaucoup rien quand me répondant...merci beaucoup...

                  Ensuite,
                  J'ai essayé ton code pour voir si ça marcher...
                  Résultat ma MsgBox me renvoie
                  DELETE FROM dbo.client WHERE nom ="toto";
                  Donc ça c'est bon... c'est normal...

                  Mais j'ai toujours la même erreur sur mon cmd.ExecuteNonQuery => "Nom de colonne non valide : 'toto'."
                  1. Webmaster
                    Non ta varaible est OK ... c'est juste qu'il faut enquoter la chaine dans la requete, pour que SQL Server comprenne que c'est une chaine ...

                    Donc juste un truc comme
                    cmd.CommandText = "DELETE FROM dbo.client WHERE nom = """ & ListBox1.SelectedItem.ToString & """ ; "
                    1. Alors en faite tu me demande de convertir le TOTO en string, c'est ça ?

                      Mais mon TOTO (=> & Listbox1.SelectedItem) est, d'après le débogage du logiciel déjà un string...
                      Il me dit =>
                      ListBox1.SelectedItem = "Toto" {String}


                      Et ensuite sur la ligne du "cmd.ExecuteNonQuery", il dit "Nom de colonne non valide : 'Toto'." et aussi que le "
                      ExecuteNonQuery () As Integer
                      "

                      Donc je comprends plus du tout