0

As a new user to .Net programming I am trying to understand why this connection is failing. The catch exception is run to inform me of such. Can someone please point out what is wrong in my code. many thanks

Imports System.Data.OleDb

Public Class DbTest

    Public buttonName As String

    'Dim con1 As New OleDbConnection("Provider = Microsoft.ACE.OLEDB.12.0;Data Source=C:\domain\storage2.accdb")

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

        lblRacks.Text = buttonName

        Dim connetionString As String
        Dim oledbCnn As OleDbConnection
        Dim oledbCmd As OleDbCommand
        Dim sql As String

        connetionString = "Provider = Microsoft.ACE.OLEDB.12.0;Data Source=C:\domain\storage2.accdb"
        sql = "SELECT [Rack_code] FROM Racks Where [Rack_code] = '" & buttonName & "'"
            oledbCnn = New OleDbConnection(connetionString)
        Try
            oledbCnn.Open()
            oledbCmd = New OleDbCommand(sql, oledbCnn)
            Dim oledbReader As OleDbDataReader = oledbCmd.ExecuteReader()
            While oledbReader.Read
                MsgBox(oledbReader.Item(0) & "  -  " & oledbReader.Item(1) & "  -  " & oledbReader.Item(2))
            End While
            oledbReader.Close()
            oledbCmd.Dispose()
            oledbCnn.Close()
        Catch ex As Exception
            MsgBox("Can not open connection ! ")
        End Try


    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.Close()
    End Sub



End Class
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
user1532468
  • 1,723
  • 8
  • 41
  • 80
  • 3
    Don't write a useless message in your catch block. Show us the value of ex.Message instead. You will get a more precise understanding of what doesn't work – Steve Oct 27 '13 at 20:24
  • @Steve 'No value given for one or more required parameters' – user1532468 Oct 27 '13 at 20:28
  • 1
    Is `buttonName` empty? I don't see where you set it. – OneFineDay Oct 27 '13 at 20:31
  • 1
    Based on that error, you don't have a field named Rack_code or a table named Racks. – LarsTech Oct 27 '13 at 20:32
  • 2
    The error message means that one of your fields is not recognized and thus the name is treated as a parameter and is missing. Now you have only one field 'Rack_Code'. Are you sure that this is the field name. Finally let me get this right. You query the database asking for a Rack_Code but you already know the Rack_Code value? (It is in the WHERE part) What you are really trying to do with this query? – Steve Oct 27 '13 at 20:33
  • Little Bobby Tables alert! – Uwe Keim Oct 27 '13 at 21:06
  • When you have an issue like this, please remove (or comment out) relevant Try/Catch blocks. This will allow you not only to see the exact error message, but also the line, at which such error occurs. Both pieces of information are crucial for troubleshooting and can greatly help us help you. – Victor Zakharov Oct 27 '13 at 22:17
  • @Steve I definitely have a table called 'Racks' and a field called 'Rack code' (notice the space in the name that is why I use []. Is that correct. The goal is to place the value from the sql query and place in a textbox 'txtColsTextBox'. Thanks – user1532468 Oct 28 '13 at 09:29
  • But if you have a space between Rack and Code then your should keep the space and not change to an underscore. That's the problem – Steve Oct 28 '13 at 09:34

3 Answers3

3

The error message means that your query contains a name that is not recognized as the name of a field or the name of the table. Thus, that name, is treated as a parameter but the OleDbCommand has no parameter defined thus the error message.
In your query you have only one field and is named Rack_Code while the table is named Racks.
You should check if these are really the names of your objects.

However your code has a couple of other problems.
You query the database asking for the value of Rack_Code but you already know that value because the WHERE clause is WHERE Rack_Code = ....

Finally, if that query succeed to run, you will have another problem because you have asked for only one field (the Rack_Code) but in the loop you try to show the values from three fields (Item(0), Item(1) and Item(2), but two items are missing from the SELECT field list.

EDIT Following your comment under the question. If you have a space between the word Rack and the word Code, then you should use that field name keeping the space and not substitute it with an underscore

sql = "SELECT [Rack code] FROM Racks Where [Rack code] = ....."

So, I would change your code to this one

Try
    sql = "SELECT [Rack Code], SecondFieldName, ThirdFieldName " & _ 
           "FROM Racks Where [Rack Code] = ?"
    Using oledbCnn = New OleDbConnection(connetionString)
    Using oledbCmd = New OleDbCommand(sql, oledbCnn)
        oledbCnn.Open()
        oledbCmd.Parameters.AddWithValue("@p1", Convert.ToInt32(buttonname))
        Using oledbReader = oledbCmd.ExecuteReader()
            if oledbReader.Read() Then
                txtCols.Text = oledbReader.Item(0).ToString() & _ 
                               "  -  " & oledbReader.Item(1).ToString() & _ 
                               "  -  " & oledbReader.Item(2).ToString())
            Else
                txtCols.Text = "No records found for the Rack Code used"
            End If
        End Using
    End Using
    End Using
Catch ex As Exception
    MsgBox("Problems executing command: " & ex.Message)
End Try

I have changed your query to use a parameterized approach, of course, I suppose that the variable buttonname is correctly initialized for some actual Rack Code value

Steve
  • 213,761
  • 22
  • 232
  • 286
  • Thank you for amending code. I now get 'data type mismatch'. I realise that this because Rack Code is an integer. The problem I have is that 'buttonname' is a string but the value being returned from the db is Integer. What do I need to change in code to correct this. Thanks – user1532468 Oct 28 '13 at 10:13
  • The query on Rack Code requires an integer, but AddWithValue looks at the datatype of the parameter to decide about the datatype to pass. So, you could define manually the Parameter with all the properties, or just convert to an integer the buttonname (assuming that you have checked the buttonname contains effectively a number), answer updated, please refresh – Steve Oct 28 '13 at 10:16
  • buttonName needs to be a string in order to lblRacks.Text = buttonName and also query the db. It is the return value from db that need to be integer. Thanks – user1532468 Oct 28 '13 at 10:21
  • And in the code above buttonname stays as string, none change it. The Convert.ToInt32 serves to say to the AddWithValue: "I want this parameter as an integer, not as string" – Steve Oct 28 '13 at 10:24
  • I am still getting 'Data type mismatch'. The problem seems to me that perhaps I haven't explained my correctly. buttonName is a string that queries the db and in this case would return 'A'. I also have field Cols that is an integer that I need to display in textbox not buttonname. buttonName just queries the db and based upon the value will return the appropriate value from Cols into textbox. Thanks – user1532468 Oct 28 '13 at 10:29
  • It is also complaing about end using being missing. I am not familiar with this command and have just placed anothe end using after your secode one. It is also stating: Variable 'oledbCnn' hides a variable in an enclosing block. Thanks – user1532468 Oct 28 '13 at 10:46
  • Modified the sql to: sql = "SELECT Cols FROM Racks Where [Rack code] = '" & buttonName & "'" and it works fine now thanks very much Steve. – user1532468 Oct 28 '13 at 11:00
  • OK, fixed the End Using missing. Now for the warning (oledbCnn) that's could be fixed removing the first declaration of oledbCnn and oledbCmd. A final note. You should not concatenate strings to build commands. The parameterized query avoid serious security problems. Look here for a [funny explanation of Sql Iniection](http://stackoverflow.com/questions/332365/how-does-the-sql-injection-from-the-bobby-tables-xkcd-comic-work) – Steve Oct 28 '13 at 11:05
2

Within your source there are a few points I would like you to check.

  1. You do not set buttonName, or we can't see it. so it may be empty and your recordSet will probably be empty
  2. You select only one field out of your table (see: SELECT [Rack_code] FROM Racks ...) but you try to access more than one field (see source below)
  3. Anytime you catch an exception you should log/print/trace exception message. (see MSDN)

--

While oledbReader.Read
      ' Item(1) ?? Item(2) ??? try removing those and just select Item(0)
      MsgBox(oledbReader.Item(0) & "  -  " & oledbReader.Item(1) & "  -  " & oledbReader.Item(2))
End While

You can find some good examples how to query databases with oledb in MSDN - OleDbDataReader or Read-Method example

Pilgerstorfer Franz
  • 8,303
  • 3
  • 41
  • 54
  • Yes I realize that your first 2 comments are correct and I have taken on board your point 3. One thing, how do you trace exception? Thanks – user1532468 Oct 28 '13 at 10:17
  • there are several possibilities. starting by simple `Debug.Write(ex.Message)`, or `Trace.Write` to get your message even in **release builds** or using an [external component, eg: Log4net](http://logging.apache.org/log4net/) to log it within a custome place – Pilgerstorfer Franz Oct 28 '13 at 10:19
  • Thank you. I shall check it out. – user1532468 Oct 28 '13 at 10:22
2

As explained in the comments, your WHERE parameter seems not to be set:

Public buttonName As String

Private Sub racksfrm_Load(ByVal sender As System.Object,... Handles MyBase.Load

lblRacks.Text = buttonName

No where does buttonName take on a value. Set this to some default value when initialized:

Public buttonName As String = "foo"

Second, your query is meaningless and wrong. If you know the Rack_Code (the WHERE) there is no reason for it to also be the SELECT column. It is wrong because in just a few lines, your code will be looking for THREE columns in the result:

 MsgBox(oledbReader.Item(0) & "  -  " & oledbReader.Item(1) & "  -  " & _
        oledbReader.Item(2))

Your query should be more like: SELECT X, Y, Z FROM Racks WHERE Rack_Code ='" & buttonName & "'"

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
  • buttonName is set from another form. Here is part of the code: frmRacks.buttonName = btn.Name.Replace("btn", "") frmRacks.Show() – user1532468 Oct 28 '13 at 10:19