在 Access/VBA 開發中,動態判斷資料表是否存在是常見需求。本文分析一段有缺陷的 DAO 程式碼,修正參數傳遞錯誤,並提供更高效的系統表查詢替代方案。
Function fExistTable(strTableName As String) As Integer
Dim db As Database, i As Integer
Set db = DBEngine.Workspaces(0).Databases(0)
fExistTable = False
db.TableDefs.Refresh
For i = 0 To db.TableDefs.Count - 1
If strTableName = db.TableDefs(i).Name Then
fExistTable = True
Exit For
End If
Next i
Set db = Nothing
End Function
' 呼叫錯誤:缺少參數
Private Sub 命令0_Click()
fExistTable ' 編譯錯誤:引數不符合
End Sub
Private Sub 命令0_Click()
Dim tableExists As Boolean
tableExists = fExistTable("需判斷的已知表名") ' 傳入表名字串
If tableExists Then
MsgBox "表格存在"
Else
MsgBox "表格不存在"
End If
End Sub
DAO 遍歷集合需載入所有表定義,大資料庫時較慢。直接查詢系統表僅需一次索引掃描。
SELECT COUNT(*) AS Qty
FROM MSysObjects
WHERE Name = '需判斷的已知表名' AND Type = 1; -- Type=1 為本地資料表
Function TableExists(ByVal tableName As String) As Boolean
Dim db As DAO.Database, rs As DAO.Recordset
Set db = CurrentDb
Set rs = db.OpenRecordset("SELECT 1 FROM MSysObjects WHERE Name = '" & tableName & "' AND Type = 1", dbOpenSnapshot)
TableExists = Not rs.EOF
rs.Close: Set rs = Nothing
Set db = Nothing
End Function
| 資料庫 | 判斷表是否存在 SQL |
|---|---|
| SQL Server | IF OBJECT_ID('schema.table', 'U') IS NOT NULL ... 或 SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'table' |
| MySQL | SHOW TABLES LIKE 'table'; 或 SELECT 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db' AND TABLE_NAME = 'table' |
| Oracle | SELECT 1 FROM user_tables WHERE table_name = UPPER('table'); |
| PostgreSQL | SELECT 1 FROM information_schema.tables WHERE table_name = 'table'; |
TableExists(),便於維護與移植。判斷表存在的核心邏輯簡單,但實作細節決定效能與穩健度。修正參數傳遞錯誤是基礎,改用系統表查詢才是進階。跨平台開發時,建立統一的 TableExists 介面封裝各資料庫差異,讓上層業務碼保持乾淨。