8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

检查访问表是否存在

thefourtheye 2月前

73 0

我想要记录网站访问的 IP、日期时间、客户端和引用数据以访问数据库,但我计划将每天的日志数据记录在单独的表中,例如将记录 2010 年 6 月 6 日的日志...

我想记录网站访问的 IP、日期时间、客户端和推荐者数据以访问数据库,但我计划将每天的日志数据记录在单独的表中,例如 2010 年 6 月 6 日的日志将记录在名为 2010_06_06 的表中。当日期更改时,我将创建一个名为 2010_06_07 的表。但问题是如果此表已创建。

关于如何检查 Access 中表是否存在,有什么建议吗?

帖子版权声明 1、本帖标题:检查访问表是否存在
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由thefourtheye在本站《ms-access》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 您可能想要考虑使用一个表,然后使用参数化查询来生成“每日”视图。这将为您提供更大的灵活性。例如,如果您想按周查看结果怎么办?使用查询,只需更改参数的日期即可。如果您有七个表,则必须实际创建包含特定表的联合查询。

  • 您可以使用隐藏的系统表 MSysObjects 来检查表是否存在:

    If Not IsNull(DlookUp("Name","MSysObjects","Name='TableName'")) Then
        'Table Exists
    

    不过,我同意每天创建新表是一个非常糟糕的主意。

    编辑:我应该补充一点,表有类型 1、4 或 6,并且不同类型的其他对象可能具有与表相同的名称,因此最好这样说:

    If Not IsNull(DlookUp("Name","MSysObjects","Name='TableName' And Type In (1,4,6)")) Then
        'Table Exists
    

    但是,不可能创建与查询同名的表,因此如果您需要查找来测试名称,最好将 5(即查询)添加到类型列表中。

  • 有:SELECT [Name] FROM MSysObjects WHERE [Name]='TableName' 并输入(1,4,6)

  • 这是另一种解决方案,比循环遍历所有表格要快一些。

    Public Function doesTableExist(strTableName As String) As Boolean
        Dim db As DAO.Database
        Dim td As DAO.TableDef
        Set db = CurrentDb
        On Error Resume Next
        Set td = db.TableDefs(strTableName)
        doesTableExist = (Err.Number = 0)
        Err.Clear
    End Function
    
  • 抱歉,这是 0 的赋值吗?doesTableExist = (Err.Number = 0) 我有点困惑这一行是什么意思

  • Err.Number = 0 是一个比较。它的结果是一个布尔值,然后将其赋值给 doesTableExist。

  • 几年前,我测试了各种查找表是否存在的方法。下面是我实现的所有方法的代码,包括我的简单测试例程。

        Public Function TableExists(strTableName As String, Optional ysnRefresh As Boolean, Optional db As DAO.Database) As Boolean
        ' Originally Based on Tony Toews function in TempTables.MDB, http://www.granite.ab.ca/access/temptables.htm
        ' Based on testing, when passed an existing database variable, this is the fastest
        On Error GoTo errHandler
          Dim tdf As DAO.TableDef
        
          If db Is Nothing Then Set db = CurrentDb()
          If ysnRefresh Then db.TableDefs.Refresh
          Set tdf = db(strTableName)
          TableExists = True
        
        exitRoutine:
          Set tdf = Nothing
          Exit Function
        
        errHandler:
          Select Case Err.Number
            Case 3265
              TableExists = False
            Case Else
              MsgBox Err.Number & ": " & Err.Description, vbCritical, "Error in mdlBackup.TableExists()"
          End Select
          Resume exitRoutine
        End Function
        
        Public Function TableExists2(strTableName As String, Optional ysnRefresh As Boolean, Optional db As DAO.Database) As Boolean
        On Error GoTo errHandler
          Dim bolCleanupDB As Boolean
          Dim tdf As DAO.TableDef
        
          If db Is Nothing Then
             Set db = CurrentDb()
             bolCleanupDB = True
          End If
          If ysnRefresh Then db.TableDefs.Refresh
          For Each tdf In db.TableDefs
            If tdf.name = strTableName Then
               TableExists2 = True
               Exit For
            End If
          Next tdf
        
        exitRoutine:
          Set tdf = Nothing
          If bolCleanupDB Then
             Set db = Nothing
          End If
          Exit Function
        
        errHandler:
          MsgBox Err.Number & ": " & Err.Description, vbCritical, "Error in mdlBackup.TableExists1()"
          Resume exitRoutine
        End Function
        
        Public Function TableExists3(strTableName As String, _
             Optional db As DAO.Database) As Boolean
        ' Based on testing, when NOT passed an existing database variable, this is the fastest
        On Error GoTo errHandler
          Dim strSQL As String
          Dim rs As DAO.Recordset
        
          If db Is Nothing Then Set db = CurrentDb()
          strSQL = "SELECT MSysObjects.Name FROM MSysObjects "
          strSQL = strSQL & "WHERE MSysObjects.Name=" & Chr(34) & strTableName & Chr(34)
          strSQL = strSQL & " AND MSysObjects.Type=6;"
          Set rs = db.OpenRecordset(strSQL)
          TableExists3 = (rs.RecordCount <> 0)
          
        exitRoutine:
          If Not (rs Is Nothing) Then
             rs.Close
             Set rs = Nothing
          End If
          Exit Function
        
        errHandler:
          MsgBox Err.Number & ": " & Err.Description, vbCritical, _
             "Error in TableExists1()"
          Resume exitRoutine
        End Function
        
        Public Sub TestTableExists(strTableName As String, intLoopCount As Integer)
          Dim dteStart As Date
          Dim i As Integer
          Dim bolResults As Boolean
          
          dteStart = Now()
          For i = 0 To intLoopCount
            bolResults = TableExists(strTableName, , CurrentDB())
          Next i
          Debug.Print "TableExists (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")
        
          dteStart = Now()
          For i = 0 To intLoopCount
            bolResults = TableExists2(strTableName, , CurrentDB())
          Next i
          Debug.Print "TableExists2 (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")
        
          dteStart = Now()
          For i = 0 To intLoopCount
            bolResults = TableExists3(strTableName, CurrentDB())
          Next i
          Debug.Print "TableExists3 (" & intLoopCount & "): " & Format(Now() - dteStart, "nn:ss")
        End Sub
    
  • TableExists 和 TableExists2 适用于(mysql odbc)链接表;但是 TableExists3 不适用。

  • Kosh 2月前 0 只看Ta
    引用 10

    我发现查询系统表或 tabledef 不可靠,并且会在定期创建和删除表的脚本中引入不可预测的行为。

    根据我的结果,我的假设是这些表不一定在 CREATE 或的 DROP ,或者并发问题阻止我获得准确的结果。

    我发现以下方法更可靠:

    Public Function TableExists(theDatabase As Access.Application, _
        tableName As String) As Boolean
    
        ' Presume that table does not exist.
        TableExists = False
    
        ' Define iterator to query the object model.
        Dim iTable As Integer
    
        ' Loop through object catalogue and compare with search term.
        For iTable = 0 To theDatabase.CurrentData.AllTables.Count - 1
            If theDatabase.CurrentData.AllTables(iTable).Name = tableName Then
                TableExists = True
                Exit Function
            End If
        Next iTable
    
    End Function
    

    除非表的集合非常庞大,否则迭代时不应该出现运行时问题。

  • 这个问题已经很老了,但我发现没有一个答案令人满意,因为:

    • 它们不处理“坏”链接表的情况,其中链接表指向不存在的数据库或表。
    • 由于链接表可能非常大,我们必须能够通过快速查询来检查它们。

    以下是我的简单但更完整的解决方案:

        Function isTableOk(tblName As String) As Boolean
        'works with local or linked tables
            Dim db As DAO.Database, rs As DAO.Recordset
            Dim sSql As String
            sSql = "SELECT TOP 1 ""xxx"" AS Expr1 FROM [" & tblName & "]"
            
            On Error Resume Next
            Err.Clear
            Set db = CurrentDb
            Set rs = db.OpenRecordset(sSql)
            isTableOk = (Err.Number = 0)
            rs.Close
        End Function
    

    您甚至可以 使用此版本 外部

        Function isTableOk(tblName As String, Optional dbName As String) As Boolean
        'works with local or linked tables, or even tables in external db (if dbName is provided)
        
            Dim db As DAO.Database, rs As DAO.Recordset
            Dim sSql As String
            
            Set db = CurrentDb
            sSql = "SELECT TOP 1 'xxx' AS Expr1 FROM [" & tblName & "]"
            If Len(dbName) > 0 Then 'external db 
                sSql = sSql & " IN '" & dbName & "'"
            End If
            Err.Clear
            On Error Resume Next
            Set rs = db.OpenRecordset(sSql)
            isTableOk = (Err.Number = 0)
            rs.Close
        End Function
    
  • 引用 12

    抱歉,isTableOk = (Err.Number = 0) 这一行是什么意思?

  • @r0berts - 这是使用 Err 对象(Error 对象)来检查是否发生错误。如果数字大于零,则表示出现了问题,并且(从技术上来说)该表存在问题。

  • 这是你可以拥有的最短的解决方案:

    Public Function TableExists(ByVal Table As String) As Boolean
        On Error Resume Next
        TableExists = (DCount("*", Table) >= 0)
    End Function
    

    我已经测试过它的性能,它比在 TableDefs 或 MySysObjects 表中查找存在性要快得多。而且它正在处理不存在的链接表。如果表已声明但无法访问,它将返回 FALSE .

    它是如何工作的?如果表存在,它的记录数将始终 >= 0,因此它将返回 TRUE 。如果表不存在或无法访问,第二行将触发错误。由于错误处理,它将直接跳转到下一行,即 End Function 。因为 FALSE 是布尔函数的默认结果(如果未设置),否则,函数结果将是 FALSE .

  • 'OfficePaper.cc/functions/awa-cømezwe
    'chernipeski*duck.com
    
    Public Function IsTable( _
    Optional ByVal LookingFor = 0, _
    Optional ByVal IncludeLinked = False) _
    As Boolean
        a = IIf(IncludeLinked, "1,6", "1")
        c = "Type In (" & a & ") AND Name='" & LookingFor & "'"
        r = DLookup("Name", "MSysObjects", c)
        r = Nz(r, "")
        IsTable = (LookingFor = r)
    End Function
    

    run-time snapshot

  • 引用 16

    我意识到这是一个非常老的问题,但上面的答案都没有真正符合我的要求。

    有些使用了错误干预,我最不喜欢这种做法。有些使用了循环搜索,迭代直到找到或未找到所需的表(可能对 TableDefs 中的每个表重复此操作)。其他则使用 MSys 表上的搜索(这是一种不错的方法,但使用 DLookup DCount )。

    此版本使用二进制切碎,将每次需要检查的数据量减少一半......

    Public Function TableExists(tblName As String) As Boolean
        'Initialise...
        Dim cdb As DAO.Database: Set cdb = CurrentDb
        Dim s As Integer, e As Integer, o As Integer, p As Integer, x As Integer
        Dim running As Boolean, found As Boolean
        found = False: running = True
        x = 0
        'Set the start, end and pointer...
        s = 0: e = cdb.TableDefs.count - 1: o = -1: p = (e - s) / 2
        'Test whether we're still running...
        While running
            'Test the current pointer in the collection against the required...
            found = cdb.TableDefs(p).name = tblName
            'If it's not found then check whether required is before or after the pointer...
            s = (tblName >= cdb.TableDefs(p).name And p) Or _
                (tblName <  cdb.TableDefs(p).name And s)
            e = (tblName <= cdb.TableDefs(p).name And p) Or _
                (tblName >  cdb.TableDefs(p).name And e)
            'Relocate the pointer, taking into account odds/evens...
            p = (s + (e - s) / 2)
            p = p + -(s = e - 1 And o = p)
            'Determine whether we're still running...
            running = (x < cdb.TableDefs.count) And Not found And (o <> p)
            x = x + 1 'Debugging trap, just in case of infinite loops
            o = p
        Wend
        TableExists = found
    End Function
    

    我讨厌 Access。

返回
作者最近主题: