代码之家  ›  专栏  ›  技术社区  ›  HasanG Joe Dabones

检查访问表是否存在

  •  15
  • HasanG Joe Dabones  · 技术社区  · 14 年前

    4 回复  |  直到 14 年前
        1
  •  42
  •   Fionnuala    14 年前

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

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

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

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

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

        2
  •  8
  •   David-W-Fenton    14 年前

    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
    
        3
  •  7
  •   Jörg Brenninkmeyer    8 年前

    这是另一个解决方案,比在所有表上循环要快一点。

    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
    
        4
  •  2
  •   Nathan Tuggy TonyLuigiC    9 年前

    根据我的研究结果,我的假设是这些表不一定在某个时刻更新 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
    

    除非有一个惊人庞大的表集合,否则迭代不应该有运行时问题。

        5
  •  1
  •   iDevlop    5 年前

    • 它们不处理“坏”链接表的情况,即链接表指向不存在的db或表。

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

    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