如何使用参数在 Access Table 中添加行?

How to add rows in an Access Table with parameters?

这是我的功能:

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

我是这样调用函数的:

            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)

这是构建的命令字符串输出:

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)

这是我收到的错误:

现在我不知道我可能有什么语法错误,我在这里寻找另一个在这个 Stack 问题中没有问题的人:Insert data into SQL database in VB.NET,我的语法相似。

我不知道出了什么问题,如果 Access 数据库列不是数据类型 Short/Long 文本,它会给出语法错误吗?

参数添加正确(检查调试)。

我很笨

操作顺序错了,函数应该是这样的:

Function SQL_InsertUpdate(mySQLConnection As OleDbConnection, mySQLCommand As String, mySQLTable As String, mySQLTableColumns() As String, myParameters() As String)


    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) & ", "
    Next

    myStringConstruct = Strings.Left(myStringConstruct, Len(myStringConstruct) - 2)
    myStringConstruct = myStringConstruct & ")"

    Dim SQLCommand As OleDbCommand = New OleDbCommand(myStringConstruct, mySQLConnection)

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

    SQLCommand.ExecuteNonQuery()
End Function

基本上,我传递的是一个不完整的命令。

实际上,我经常发现创建复杂的插入例程工作量太大。更糟糕的是,我常常不关心或不想提供所有的列。

.net 因此为您提供了所谓的命令生成器。

这在很大程度上意味着您可以按照 VBA Access 代码的工作方式编写大量代码。

所以,假设我想添加一个新行 - table 可能有 50 列,但我并不关心。

所以,我可以这样写代码:

    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")

因此,请注意我们如何不必拥有一些复杂的插入语句,并且我们不必编写一些循环来告知列数。所以 .net 数据操作已经为您构建了所有这些东西 - 很少甚至几乎没有理由让您尝试 re-invent 这里的轮子。

还有我拥有的两个方便的花花公子代码例程?它们是:

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

现在,我真的很自由,可以编写我的常规程序。

所以,您需要说加载一个网格,甚至是一个组合框?您现在可以这样做:

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

那么,对于一些行的简单插入,甚至编辑?无需创建带有大量参数的巨大插入语句。只需创建一个数据 table,然后使用一个简单的数据行来添加新行,甚至更新现有行。

上面的美妙之处在于您不仅消除了一大堆参数,而且还获得了参数安全,甚至类型转换。所以,你可以这样做:

 OneRow("InvoiceDate") = Date.Today

因此,可以在代码中使用强类型值“money”或整数,或日期时间 - 在大多数情况下不需要混乱的格式转换。

这个所谓的“数据库”首先可以非常方便,而且通常对于某些操作来说,设置时间和学习曲线要​​少得多,然后说使用 EF,甚至是以前的数据集设计器(EF =“Entity framework",它的工作原理与旧的数据集设计器系统非常相似——但是这些对象模型系统的引入可能是您刚开始时需要咀嚼的一个大系统。

但是,不,不要编写自己的循环代码来为更新命令写出和创建所有列。 (或插入命令 - 注意一个例程如何处理更新或插入。你甚至可以使用 row.Delete 然后调用更新例程 - 它也可以工作!!

如果您仔细想想,这确实需要大量工作,并且针对此提议存在内置系统 - 省去了您 re-invent 方向盘的麻烦。