0

我试图让这个例程更新我的自动日志表访问。每次运行它时,INSERT 命令都会出现语法错误。现在,当我从命令生成器中查看 INSERT 命令时,我可以看到缺少的值被问号替换,但我不明白为什么。这是我的代码:

Function Autolog(ByRef LogEntry As String, ByVal Userid As Integer)
    Dim Table_ As String = "Table1"
    Dim sql As String = "Select * from autolog"
    Dim MDBConnString_ As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Freightmasterbe\Freightmaster.accdb;"
    Dim cnn As OleDbConnection = New OleDbConnection(MDBConnString_)
    Dim DS As New DataSet
    Dim Da As OleDbDataAdapter
    Dim StrHOstName As String


    Da = New OleDb.OleDbDataAdapter(sql, cnn)

    Da.Fill(DS, "Rst")
    ' cnn.Close()
    Dim cb As New OleDb.OleDbCommandBuilder(Da)
    Dim DSNewRow As DataRow
    DSNewRow = DS.Tables("Rst").NewRow()

    DSNewRow.Item("UserID") = Userid
    DSNewRow.Item("Action") = LogEntry

    DSNewRow.Item("RemoteComputerName") = My.Computer.Name
    StrHOstName = System.Net.Dns.GetHostName()
    DSNewRow.Item("RemoteIP") = System.Net.Dns.GetHostEntry(StrHOstName).AddressList(0).ToString()

    DS.Tables("RST").Rows.Add(DSNewRow)
    '   Da.ContinueUpdateOnError = True

    Da.Update(DS, "RST")
    Beep()
End Function

这是我查询命令生成器插入命令时得到的

即时窗口

CanRaiseEventsInternal: True
CommandText: "INSERT INTO autolog (UserID, Action, TimeStamp, RemoteComputerName, RemoteIP) VALUES (?, ?, ?, ?, ?)"
CommandTimeout: 30
CommandType: Text {1}
Connection: {System.Data.OleDb.OleDbConnection}
Connection (DbCommand): {System.Data.OleDb.OleDbConnection}
Container: Nothing
DbConnection: {System.Data.OleDb.OleDbConnection}
DbParameterCollection: {System.Data.OleDb.OleDbParameterCollection}
DbTransaction: Nothing
DesignMode: False
DesignTimeVisible: True
Events: {System.ComponentModel.EventHandlerList}
ObjectID: 4
Parameters: {System.Data.OleDb.OleDbParameterCollection}
Parameters (DbCommand): {System.Data.OleDb.OleDbParameterCollection}
Site: Nothing
Transaction: Nothing
Transaction (DbCommand): Nothing
UpdatedRowSource: None {0}
4

2 回答 2

0

非常感谢您的评论。添加前缀和后缀产生了重大影响,并且在第一个答案中使用最初发布的代码效果很好。其他回应也解释了很多。(哦,我多么渴望简单地使用 sql 语句插入数据的美好时光!

于 2021-12-27T14:14:11.330 回答
0

根据这个帖子ActionAccess数据库引擎的一个保留字。因此,您需要使用QuotePrefixQuoteSuffix,如下面的代码所示。此外,任何具有Dispose方法的对象都应该使用using 语句或 call Dispose

如果您希望使用OleDbCommandBuilder将一行插入您的 Access 数据库:

创建表(名称:Autolog)

在此处输入图像描述

CREATE TABLE Autolog(ID AUTOINCREMENT not null primary key,
                    [UserID] varchar(25),
                    [Action] varchar(125),
                    [RemoteComputerName] varchar(50),
                    [RemoteIP] varchar(50));

然后,尝试以下(已经过测试):

Private _connectionStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Freightmasterbe\Freightmaster.accdb;"

Public Function TblAutologInsert(ByVal LogEntry As String, ByVal UserId As Integer) As Integer
    Dim dt As DataTable = New DataTable()

    Dim remoteComputerName As String = My.Computer.Name
    Dim strHostName As String = System.Net.Dns.GetHostName()
    Dim remoteIP = System.Net.Dns.GetHostEntry(strHostName).AddressList(0).ToString()

    Using cnn As OleDbConnection = New OleDbConnection(_connectionStr)
        'open
        cnn.Open()

        Using da As OleDbDataAdapter = New OleDbDataAdapter("SELECT * from Autolog order by Id", cnn)
            'get data from database
            da.Fill(dt)

            Using cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
                'needed if database column name contains either spaces or is a reserved word
                cb.QuotePrefix = "["
                cb.QuoteSuffix = "]"

                'new row
                Dim row As DataRow = dt.NewRow()

                'set values
                row.Item("UserID") = UserId
                row.Item("Action") = LogEntry
                row.Item("RemoteComputerName") = remoteComputerName
                row.Item("RemoteIP") = remoteIP

                'add row to DataTable
                dt.Rows.Add(row)

                'get insert command
                da.InsertCommand = cb.GetInsertCommand(True)
                'Debug.WriteLine("da.InsertCommand.CommandText: " & da.InsertCommand.CommandText)

                'update database and return number of rows affected
                Return da.Update(dt)
            End Using
        End Using
    End Using
End Function

用法

Dim rowsAffected As Integer = 0

'insert test data
rowsAffected += HelperAccess.TblAutologInsert("test 1", 1)
rowsAffected += HelperAccess.TblAutologInsert("test 2", 2)
rowsAffected += HelperAccess.TblAutologInsert("test 3", 3)

Debug.WriteLine("rowsAffected: " & rowsAffected.ToString())

这是一些通过“Id”更新记录的代码。

Public Function TblAutologUpdate(LogEntry As String, UserId As Integer, id As Integer) As Integer
    Dim dt As DataTable = New DataTable()

    Dim remoteComputerName As String = My.Computer.Name
    Dim strHostName As String = System.Net.Dns.GetHostName()
    Dim remoteIP = System.Net.Dns.GetHostEntry(strHostName).AddressList(0).ToString()

    Using cnn As OleDbConnection = New OleDbConnection(_connectionStr)
        'open
        cnn.Open()

        Using cmd As OleDbCommand = New OleDbCommand("SELECT * from Autolog where Id = ?", cnn)
            'OLEDB doesn't use named parameters in SQL. Any names specified will be discarded and replaced with '?'
            'However, specifying names in the parameter 'Add' statement can be useful for debugging
            'Since OLEDB uses anonymous names, the order which the parameters are added is important
            'if a column is referenced more than once in the SQL, then it must be added as a parameter more than once
            'parameters must be added in the order that they are specified in the SQL
            'if a value is null, the value must be assigned as: DBNull.Value

            'add parameters
            With cmd.Parameters
                .Add("!id", OleDbType.Integer).Value = id
            End With

            Using da As OleDbDataAdapter = New OleDbDataAdapter(cmd)
                'get data from database
                da.Fill(dt)

                Using cb As OleDbCommandBuilder = New OleDbCommandBuilder(da)
                    'needed if database column name contains either spaces or is a reserved word
                    cb.QuotePrefix = "["
                    cb.QuoteSuffix = "]"

                    If dt.Rows.Count >= 0 Then
                        'set value
                        Dim row As DataRow = dt.Rows(0)

                        'set values
                        row.Item("UserID") = UserId
                        row.Item("Action") = LogEntry
                        row.Item("RemoteComputerName") = remoteComputerName
                        row.Item("RemoteIP") = remoteIP

                        'get update command
                        da.UpdateCommand = cb.GetUpdateCommand()
                       
                        'update database and return number of rows affected
                        Return da.Update(dt)
                    End If
                End Using
            End Using
        End Using
    End Using
End Function

用法

Dim rowsAffected As Integer = 0

'update
rowsAffected += HelperAccess.TblAutologUpdateById("test 2b", 2, 2)

Debug.WriteLine("rowsAffected: " & rowsAffected.ToString())

资源

于 2021-12-26T05:03:25.163 回答