A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in...

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Here's hoping someone can help a noob out..

I am working out of an old book (Beginning VB.NET Databases) circa 2004'ish... and I'm working in Visual Studio 2008 and running Windows 7 x64.

I've determined that the code for the project I am working on is sound, as I downloaded the same completed code out from WROX (the publisher of the book) and it generated the same error. I can only conclude it is some sort of permissions or new (Windows 7, Visual Studio 2008, .NET 3.5) environment issue that causing the error.

When I go to Debug my app... I get this In the "Intermediate Window":
A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in System.Data.dll

Any ideas? :confused:

Many thanks.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
That simply indicates that an exception was thrown somewhere, which is not a problem in and of itself. Exceptions are allowed top be thrown. It's when an exception is thrown and not caught that you've got a problem. Does the app crash when you run it? If not, the exception is being caught. In that case, you likely have nothing to worry about. Do you have any code in your app that might be catching the exception and ignoring it rather than handling it properly? If so then you should either remove it and address the cause or else include proper error handling. If not then the exception must be being handled within the Framework, so it's most likely not your issue.
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
The app runs, but the data does not populate the drop down. No other error besides this once is generated. Everything appears to be fine... except for the missing data.

I'm EXTREMELY new at this (hence the book I am studying), so what in the code would I be looking for that might generate this exception?

I'm going to attempt to attach the project from the book to this message.
 
Last edited by a moderator:

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
I've removed your attachment because, from the size, I'm fairly sure that it contained binary files, which is against forum rules. If you want to attach a project then make sure that you delete the 'obj' and 'bin' folders first.

That said, attaching a project should be a last resort. Your first option should be to post ALL the relevant code and ONLY the relevant code directly, within formatting tags using the button provided on the advanced editor. In this case, retrieving the data seems to be the issue so post the code that retrieves the data. If we can't work out what's going on from that, then we might request that you attach the whole project.
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Sorry about that... first time here... and VERY new at VB....

Like I said... on Chapter 3 of the book... so I'm EXTREMELY new at this.

Hopefully this isn't too much code.. it's basically the form and the code to retrieve the data... I left out a bit of code above and below this as I figured it wasn't relevant.

I appreciate the help.

VB.NET:
Private Sub InitializeComponent()
        Dim resources As System.ComponentModel.ComponentResourceManager = New System.ComponentModel.ComponentResourceManager(GetType(Form1))
        Me.cboCompanies = New System.Windows.Forms.ComboBox
        Me.CustomerDS1 = New ODBC_Data_Wizard.CustomerDS
        Me.txtName = New System.Windows.Forms.TextBox
        Me.txtTitle = New System.Windows.Forms.TextBox
        Me.txtPhone = New System.Windows.Forms.TextBox
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label3 = New System.Windows.Forms.Label
        Me.OdbcSelectCommand1 = New System.Data.Odbc.OdbcCommand
        Me.OdbcDataAdapter1 = New System.Data.Odbc.OdbcDataAdapter
        Me.OdbcConnection2 = New System.Data.Odbc.OdbcConnection
        CType(Me.CustomerDS1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'cboCompanies
        '
        Me.cboCompanies.DataSource = Me.CustomerDS1
        Me.cboCompanies.DisplayMember = "Table.CompanyName"
        Me.cboCompanies.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList
        Me.cboCompanies.FormattingEnabled = True
        Me.cboCompanies.Location = New System.Drawing.Point(13, 10)
        Me.cboCompanies.Name = "cboCompanies"
        Me.cboCompanies.Size = New System.Drawing.Size(267, 21)
        Me.cboCompanies.TabIndex = 0
        Me.cboCompanies.ValueMember = "Table.CustomerID"
        '
        'CustomerDS1
        '
        Me.CustomerDS1.DataSetName = "CustomerDS"
        Me.CustomerDS1.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema
        '
        'txtName
        '
        Me.txtName.Location = New System.Drawing.Point(77, 38)
        Me.txtName.Name = "txtName"
        Me.txtName.Size = New System.Drawing.Size(203, 20)
        Me.txtName.TabIndex = 1
        '
        'txtTitle
        '
        Me.txtTitle.Location = New System.Drawing.Point(77, 65)
        Me.txtTitle.Name = "txtTitle"
        Me.txtTitle.Size = New System.Drawing.Size(203, 20)
        Me.txtTitle.TabIndex = 2
        '
        'txtPhone
        '
        Me.txtPhone.Location = New System.Drawing.Point(77, 91)
        Me.txtPhone.Name = "txtPhone"
        Me.txtPhone.Size = New System.Drawing.Size(203, 20)
        Me.txtPhone.TabIndex = 3
        '
        'Label1
        '
        Me.Label1.AutoSize = True
        Me.Label1.Location = New System.Drawing.Point(33, 41)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(35, 13)
        Me.Label1.TabIndex = 4
        Me.Label1.Text = "Name"
        '
        'Label2
        '
        Me.Label2.AutoSize = True
        Me.Label2.Location = New System.Drawing.Point(33, 68)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(27, 13)
        Me.Label2.TabIndex = 5
        Me.Label2.Text = "Title"
        '
        'Label3
        '
        Me.Label3.AutoSize = True
        Me.Label3.Location = New System.Drawing.Point(33, 94)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(38, 13)
        Me.Label3.TabIndex = 6
        Me.Label3.Text = "Phone"
        '
        'OdbcSelectCommand1
        '
        Me.OdbcSelectCommand1.CommandText = "SELECT CustomerID, CompanyName, ContactName, ContactTitle, Phone" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "FROM" & _
            "Customers.csv" & Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10) & "ORDER BY CompanyName"
        Me.OdbcSelectCommand1.Connection = Me.OdbcConnection2
        '
        'OdbcDataAdapter1
        '
        Me.OdbcDataAdapter1.SelectCommand = Me.OdbcSelectCommand1
        Me.OdbcDataAdapter1.TableMappings.AddRange(New System.Data.Common.DataTableMapping() {New System.Data.Common.DataTableMapping("Table", "Table", New System.Data.Common.DataColumnMapping() {New System.Data.Common.DataColumnMapping("CustomerID", "CustomerID"), New System.Data.Common.DataColumnMapping("CompanyName", "CompanyName"), New System.Data.Common.DataColumnMapping("ContactName", "ContactName"), New System.Data.Common.DataColumnMapping("ContactTitle", "ContactTitle"), New System.Data.Common.DataColumnMapping("Phone", "Phone")})})
        '
        'OdbcConnection2
        '
        Me.OdbcConnection2.ConnectionString = resources.GetString("OdbcConnection2.ConnectionString")
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(292, 115)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.txtPhone)
        Me.Controls.Add(Me.txtTitle)
        Me.Controls.Add(Me.txtName)
        Me.Controls.Add(Me.cboCompanies)
        Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
        Me.MaximizeBox = False
        Me.MinimizeBox = False
        Me.Name = "Form1"
        Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen
        Me.Text = "ODBC Data Wizard"
        CType(Me.CustomerDS1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
That isn't the form code to retrieve the data. That's the designer generated code, i.e. the code that creates and configures the form and its controls based on your actions in the designer. The code to retrieve the data isn't even in that file. In the Solution Explorer, there is a node for your form. If you double-click that node it will open the form in the designer. If you press F7, it will open up the user code file for that form. It's in that file that you need to retrieve the data, probably in the Load event handler of the form or maybe in the Click event handler of a Button, depending on the behaviour you want.

Having said all that, you did say that you're using an old book and there are some better options these days. First up, you're using ODBC to connect, which should be your last option. You should use a data source-specific provider if you can, e.g. SqlClient for SQL Server. If that's not an option, OLE DB is the next best and then ODBC is the lowest common denominator.

Also, from VS 2005, the Data Source wizard was added, which is a better option that adding commands and adapters to your form. You might like to follow the MSDN Data Walkthroughs link in my signature for some step-by-step instructions on basic data scenarios.
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Sorry about that again. Even I should have noticed that wasn't the right code. I had even been the in form code a couple days ago.

Do you know of a newer book for beginners that covers VB.NET Databases?

The old one was all I could find.

Thanks once more.

VB.NET:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        OdbcDataAdapter1.Fill(CustomerDS1)
        Call cboCompanies_SelectedIndexChanged(Nothing, Nothing)
    End Sub

    Private Sub cboCompanies_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCompanies.SelectedIndexChanged
        For intIndex As Integer = 0 To CustomerDS1.Tables( _
        "Customers_csv").Rows.Count - 1
            If CustomerDS1.Tables("Customers_csv").Rows(intIndex).Item( _
                "CustomerID") = cboCompanies.SelectedValue Then
                txtName.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("ContactName")
                txtTitle.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("ContactTitle")
                txtPhone.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("Phone")
                Exit For
            End If
        Next
    End Sub
End Class
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
I think I know what's happening now. This is the line that retrieves the data:
VB.NET:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        [COLOR="red"]OdbcDataAdapter1.Fill(CustomerDS1)[/COLOR]
        Call cboCompanies_SelectedIndexChanged(Nothing, Nothing)
    End Sub
Because that code is in the Load event handler, on Win7 and also I think Vista, any exception thrown will be swallowed and the form will display. My guess is that you are using an invalid connection string so the connection fails and no data is retrieved, but the form displays anyway. You can find out what's actually going wrong by adding an exception handler and displaying the error information:
VB.NET:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            OdbcDataAdapter1.Fill(CustomerDS1)
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try

        Call cboCompanies_SelectedIndexChanged(Nothing, Nothing)
    End Sub
Pretty much all VB books and tutorials will cover data access because the vast majority of useful apps these days require it. Before spending money on another book, try some online resources first, e.g.

Microsoft Visual Basic .NET tutorials for Beginners
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
That definitely changed the error a bit:
A first chance exception of type 'System.NullReferenceException' occurred in ODBC Data Wizard.exe

And then generated the attached message (screen grab).
 

Attachments

  • Error.JPG
    Error.JPG
    81.2 KB · Views: 55

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Wow... and it generated that piece automatically as I built the form. I wonder why it left out the space. Odd.

That got the data to populate... but now I have a new error "NullReferenceException was unhandled - Object reference not to to an instance of an object." and it flagged this line of code:
VB.NET:
For intIndex As Integer = 0 To CustomerDS1.Tables( _
        "Customers_csv").Rows.Count - 1

Then the form crashes if I try to change anything in the form.

Many thanks for all the help. This is really helping me figure out a lot about the code.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
I think you'll find that "it" didn't leave out the space but rather whoever typed the SQL code into the designer left out the space.

As for the current issue, a NullReferenceException occurs when you try to access a member via a variable, property or some other expression that evaluates to Nothing, e.g.
VB.NET:
Dim str As String = Nothing
Dim len As Integer = str.Length
You can't get the Length of a String that doesn't exist. In your code, something on that line that has a dot after it evaluates to Nothing. When the exception is thrown, you use the debugger to determine which expression is Nothing and then you work back to where you expected an object to be assigned and that's your issue.
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Ugh... that's the problem with this book.. I've got no idea what could be wrong. I followed the tutorial to the letter... AND I've been back through their code 100 times...

No idea why I'm getting that error or how to fix it at this point...

About to abandon the entire book...

VB.NET:
Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Try
            OdbcDataAdapter1.Fill(CustomerDS1)
        Catch ex As Exception
            MessageBox.Show(ex.ToString())
        End Try
        Call cboCompanies_SelectedIndexChanged(Nothing, Nothing)
    End Sub

    Private Sub cboCompanies_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCompanies.SelectedIndexChanged
        For intIndex As Integer = 0 To CustomerDS1.Tables( _
        "Customers_csv").Rows.Count - 1
            If CustomerDS1.Tables("Customers_csv").Rows(intIndex).Item( _
                "CustomerID") = cboCompanies.SelectedValue Then
                txtName.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("ContactName")
                txtTitle.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("ContactTitle")
                txtPhone.Text = CustomerDS1.Tables( _
                    "Customers_csv").Rows(intIndex).Item("Phone")
                Exit For
            End If
        Next
    End Sub
End Class
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
Code that doesn't work properly in text books is annoying and is quite shameful, but think of it as a chance to practice your debugging skills. As I said, when the exception is thrown, that's when you do your diagnosis. When the debugger breaks, look at the line that is highlighted. You need to test each expression on that line that is followed by a dot. To do that you can use the Autos, Locals, Watch or Immediate windows, but the simplest is probably Quick Watch. Right-click the expression of interest, selecting it first if it's part of a larger expression, and select Quick Watch. That will display the value of that expression in the Quick Watch window. If it's Nothing, that's your issue. As I said, you can then work back through the code to where you expected that value to be assigned.
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Once more... many thanks for your help.

It appears that even though the dropdown is showing that data is being pulled from the database (well, csv file in the case) this is coming back as the culprit for being null "CustomerDS1.Tables("Customers_csv").Rows.Count - 1".

So how is it that it is obviously pulling data from the file (since the dropdown IS populated), but then the expression to read the rows from the file is coming back null?
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
The problem would appear to be that the code is trying to retrieve the DataTable by name without having specified that name when populating it. This code:
VB.NET:
OdbcDataAdapter1.Fill(CustomerDS1)
will create and populate an unnamed DataTable in the DataSet. In order to retrieve that table you would have to use an index rather than a name, i.e.
VB.NET:
CustomerDS1.Tables(0)
That will get the first DataTable. If you want to be able to get the table by name then you must specify the name when creating it, i.e.
VB.NET:
OdbcDataAdapter1.Fill(CustomerDS1, "Customers_csv")
 

th3gman

Member
Joined
Nov 17, 2010
Messages
16
Programming Experience
Beginner
Wow...

VB.NET:
CustomerDS1.Tables(0)

Did the trick... why it was coded the other (broken) way I have no idea. I typed the code in by hand directly from their code in the book per the books instructions.

Do you know any reason they would go about it that way when they simply could have done
VB.NET:
CustomerDS1.Tables(0)
:confused:
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
Personally, I prefer to use named tables. When you see the name in code it tells you exactly what the table is for. Using a 0 gives no indication of what the purpose of that table is. I would tend to leave the name in and add the name when calling Fill rather then the other way.
 

JohnOfStony

New member
Joined
Jul 12, 2012
Messages
2
Location
Milton Keynes
Programming Experience
10+
VB.NET/SQL 2008 EXPRESS - Connection Strings

Personally, I prefer to use named tables. When you see the name in code it tells you exactly what the table is for. Using a 0 gives no indication of what the purpose of that table is. I would tend to leave the name in and add the name when calling Fill rather then the other way.

I found this discussion very interesting as it is close to my problem. I am writing a program without a predefined database location so I can't use the wizard to create a data source connection without having to recompile for every different database location. I have done this many times in VB6 but VB.NET is unbelievably different for what should be a simple operation. VB.NET doesn't seem to support ADO which I was using in VB6 and ODBC seems to be the only option. I've tried using the connection string I used in VB6 but it throws up the error message at the start of this thread, "A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in System.Data.dll". Can you direct me to documentation on connection strings and what the various parts of a connection string do as then I should be able to figure out what's wrong with the various connection strings I have tried. I've looked at what appeared to be a useful site, SQL Server 2005 Connection String Samples - ConnectionStrings.com, but it has dozens of connection strings and not enough detail to explain which one I should use. The documentation I have found all seems centred on using wizards rather than code. The book you refer to earlier does contain code BUT for an Access database so the connection string used there doesn't work. Any help or suggestions would be much appreciated. This is particularly frustrating as I've worked in software development since 1978 and feel I should be able to sort this out myself.
 

jmcilhinney

VB.NET Forum Moderator
Staff member
Joined
Aug 17, 2004
Messages
14,723
Location
Sydney, Australia
Programming Experience
10+
I found this discussion very interesting as it is close to my problem. I am writing a program without a predefined database location so I can't use the wizard to create a data source connection without having to recompile for every different database location. I have done this many times in VB6 but VB.NET is unbelievably different for what should be a simple operation. VB.NET doesn't seem to support ADO which I was using in VB6 and ODBC seems to be the only option. I've tried using the connection string I used in VB6 but it throws up the error message at the start of this thread, "A first chance exception of type 'System.Data.Odbc.OdbcException' occurred in System.Data.dll". Can you direct me to documentation on connection strings and what the various parts of a connection string do as then I should be able to figure out what's wrong with the various connection strings I have tried. I've looked at what appeared to be a useful site, SQL Server 2005 Connection String Samples - ConnectionStrings.com, but it has dozens of connection strings and not enough detail to explain which one I should use. The documentation I have found all seems centred on using wizards rather than code. The book you refer to earlier does contain code BUT for an Access database so the connection string used there doesn't work. Any help or suggestions would be much appreciated. This is particularly frustrating as I've worked in software development since 1978 and feel I should be able to sort this out myself.

First of all, VB.NET does support ADO but you should never use it in new code. It should only be used if you have a VB6 application upgraded via the wizard.

Secondly, ODBC is not an alternative to ADO. ADO can use OLE DB providers or ODBC drivers as an intermediary between an application and a data source and so can ADO.NET.

Thirdly, if you're connecting to SQL Server then you should absolutely not be using ODBC. You should be using SqlClient, which is an ADO.NET provider dedicated to SQL Server specifically.

As for your issue, what exactly do you mean by "database location"? If you mean that the database will always have the same schema but the folder for the data file or the database instance may be different each time then that is absolutely no impediment to using the Data Source wizard. You run the wizard and it will create a connection string and store it in the config file. If you ever need to connect to a different database, e.g. after deployment, then you simply edit the config file.

If you're connecting to SQL Server then the Data Source wizard will use SqlClient under the hood. ConnectionStrings.com will almost certainly give you everything you need for a SqlClient connection string. If you have some special need then how about you explain that to us and then we can deal with that specifically? In almost all cases though, all you will need is the Data Source, the Initial Catalog or the AttachDbFileName, and Integrated Security or the User Id and Password.
 
Top Bottom