How to add rows in an Access Table with parameters?

This is my function:

Function SQL_InsertUpdate(mySQLConnection As OleDbConnection, mySQLCommand As String, mySQLTable As String, mySQLTableColumns() As String, myParameters() As String)
    Dim SQLCommand As OleDbCommand = New OleDbCommand(mySQLCommand, mySQLConnection)

    Dim myStringConstruct = mySQLCommand & " " & mySQLTable & " ("

    '==============
    For Each item In mySQLTableColumns
        myStringConstruct = myStringConstruct & item & ", "
    Next
    myStringConstruct = Strings.Left(myStringConstruct, Len(myStringConstruct) - 2)
    myStringConstruct = myStringConstruct & ") VALUES ("

    For i As Integer = 0 To mySQLTableColumns.Length - 1
        myStringConstruct = myStringConstruct & "@" & mySQLTableColumns(i) & ", "
        SQLCommand.Parameters.AddWithValue("@" & mySQLTableColumns(i), myParameters(i))
    Next

    myStringConstruct = Strings.Left(myStringConstruct, Len(myStringConstruct) - 2)
    myStringConstruct = myStringConstruct & ")"
    SQLCommand.ExecuteNonQuery()
End Function

This is how I call the function:

            Dim myParameters() As String = ({myNewID.ToString, myUser.ToString, myDepartment.ToString, mySubsidiary.ToString, myTitle.ToString, myRecurrence.ToString, myImpact.ToString, myTimeSaved.ToString, myPriority.ToString, myStatus.ToString, myTechnology.ToString, myDeveloper.ToString, myCostSave.ToString, myDescription.ToString, myCommentary.ToString, myDateSubmitted.ToString, myDateModified.ToString, myInReviewDate.ToString, myManagerReviewDate.ToString, myDigitalReviewDate.ToString, myRejectedDate.ToString, myInProgressDate.ToString, myDevelopedDate.ToString, myImplementedDate.ToString})
            Dim mySQLTableColumns() As String = ({"ID", "myUser", "myDepartment", "mySubsidiary", "myTitle", "myRecurrence", "myImpact", "myTimeSaved", "myPriority", "myStatus", "myTechnology", "myDeveloper", "myCostSave", "myDescription", "myCommentary", "myDateSubmitted", "myDateModified", "myInReviewDate", "myManagerReviewDate", "myDigitalReviewDate", "myRejectedDate", "myInProgressDate", "myDevelopedDate", "myImplementedDate"})

            SQL_InsertUpdate(SQLConnection, "INSERT INTO", "SIMSBase", mySQLTableColumns, myParameters)

This is the constructed command string output:

INSERT INTO SIMSBase (ID, myUser, myDepartment, mySubsidiary, myTitle, myRecurrence, myImpact, myTimeSaved, myPriority, myStatus, myTechnology, myDeveloper, myCostSave, myDescription, myCommentary, myDateSubmitted, myDateModified, myInReviewDate, myManagerReviewDate, myDigitalReviewDate, myRejectedDate, myInProgressDate, myDevelopedDate, myImplementedDate) VALUES (@ID, @myUser, @myDepartment, @mySubsidiary, @myTitle, @myRecurrence, @myImpact, @myTimeSaved, @myPriority, @myStatus, @myTechnology, @myDeveloper, @myCostSave, @myDescription, @myCommentary, @myDateSubmitted, @myDateModified, @myInReviewDate, @myManagerReviewDate, @myDigitalReviewDate, @myRejectedDate, @myInProgressDate, @myDevelopedDate, @myImplementedDate)

This is the error I receive:

  •   $exception  {"Syntax error in INSERT INTO statement."}  System.Data.OleDb.OleDbException
    

Now I have no clue what syntax error I could have, I looked here for another person who has no issue in this Stack question: Insert data into SQL database in VB.NET, my syntax is similar.

I don't know what is wrong, could it give out a syntax error if the Access database columns are not Data Type Short/Long Text?

The parameters are added properly (checked the debug).


Actually, I often find it too much work to create a complex insert routine. And even worse is I often don't care or want to supply all of the columns.

.net as a result has what is called a command builder for you.

And this quite much means you can write a lot of your code in a simular way to how VBA code in Access works.

So, say I want to add a new row - the table might have 50 columns, but I don't really care.

So, I can write the code this way:

    Dim rstHotels As DataTable

    rstHotels = MyRst("SELECT * FROM tblHotels WHERE ID = 0")

    ' now add 3 new hotels

    For i = 1 To 3

        Dim OneRow = rstHotels.NewRow

        OneRow("HotelName") = "Hotel #" & i
        OneRow("City") = "City #" & i
        OneRow("FirstName") = "Test First name #" & i
        OneRow("Active") = True

        rstHotels.Rows.Add(OneRow)

    Next

    ' ok, added rows to rstHotels - now write back to database

    MyRstUpDate(rstHotels, "tblHotels")

    ' or update 5 rows and do compplex processing to exising data.

    Dim rstFun As DataTable = MyRst("SELECT * from tblHotels where City = 'Banff'")

    For Each MyRow As DataRow In rstFun.Rows

        MyRow("Active") = True
        ' more complex cpde here

    Next

    ' now send data changes back to database

    MyRstUpdate(rstFun, "tblHotels")

So, note how we don't have to have some complex insert statement, and we don't hve to write some loop that gives one hoot about the number of columns. So the .net data operations have build in all this stuff for you - little or even next to no reason for you to try and re-invent the wheel here.

And the two handy dandy code routines I have? The are :

Public Function MyRst(strSQL As String) As DataTable

    Dim rstData As New DataTable
    Using conn As New OleDbConnection(My.Settings.AccessDB)
        Using cmdSQL As New OleDbCommand(strSQL, conn)
            conn.Open()
            rstData.Load(cmdSQL.ExecuteReader)
            rstData.TableName = strSQL
        End Using
    End Using

    Return rstData

End Function


Public Sub MyRstUpdate(rstData As DataTable, strTableName As String)

    Using conn As New OleDbConnection(My.Settings.AccessDB)
        Using cmdSQL As New OleDbCommand("SELECT * from " & strTableName, conn)

            Dim da As New OleDbDataAdapter(cmdSQL)
            Dim daUP As New OleDbCommandBuilder(da)
            conn.Open()
            da.Update(rstData)
        End Using
    End Using

End Sub

Now, I am really rather free to just code out my general routines.

So, you need to say load up a grid, or even a combo box? You can now do this:

ListBox1.DataSource = MyRst("SELECT ID, Salutation from tblGender ORDER BY Salutation")

So, for a simple insert, or even edit of some rows? No need to create some monster huge insert statement with a boatload of parameters. Just create a data table, and then use a simple data row to either add new rows, or even update existing ones.

The beauty of above is not only do you eliminate a boatload of parameters, but you also get parameter safe, and even type conversions. So, you can for example do this:

 OneRow("InvoiceDate") = Date.Today

Thus a strong typed value of "money" or integer, or datetime can be used in code - and no messey format convertions are required in most cases.

This so called "data base" first can be really handy, and often for some operations this is a lot less setup time and learning curve then say using EF, or even the previous dataset designer (EF = "Entity framework", which works really much like the older data set designer system - but introduction of these object model systems can be a big system to chew on when you just starting out).

But, no, don't write your own looping code to write out and create all the columns for a update command. (or insert command - note how that ONE routine can handle both updates or inserts. And you can even use row.Delete and then call tht update routine - it will also work!!.

If you think about this, that really amounts to a lot of work, and built in systems exist for this propose - saves you having to re-invent the wheel.