升迁向导从一开始就存在缺陷,并且已从最新版本的 Access 中删除。我建议不要使用它。
就个人而言,我有一个表格可以为我处理升迁。它是一个表单,上面有两个名为ConStr
和的文本框adoString
(第一个包含供 Access 使用的连接字符串,包括ODBC;
前缀,第二个包含供 ADO 使用的 ODBC 或 OLEDB 字符串)、一个名为 的按钮ToSQL
和一个名为 的列表框lstTables
。它包含以下代码:
要在加载时填充本地表:
Private Sub Form_Load()
lstTables.RowSourceType = "Value List"
Dim iterator As Variant
For Each iterator In CurrentDb.TableDefs
If Not iterator.NAME Like "MSys*" And Not iterator.NAME Like "~*" Then
lstTables.AddItem iterator.NAME
End If
Next iterator
End Sub
要将表移动到 SQL Server:
Private Sub ToSQL_Click()
Dim i1 As Variant
Dim td As DAO.TableDef
Dim NewTd As DAO.TableDef
Dim db As DAO.Database
Set db = CurrentDb
'Iterate through all selected tables
With lstTables
For Each i1 In .ItemsSelected
Set td = db.TableDefs(.ItemData(i1))
'Add a primary key if none exist
'AddPK td 'Not providing this one as it's not part of normal upscaling
'Move the table to SQL server
DoCmd.TransferDatabase acExport, "ODBC Database", _
conStr _
, acTable, .ItemData(i1), .ItemData(i1)
'Rename the local table to name_local
td.NAME = .ItemData(i1) & "_local"
'Change the remote table to the schema specified
'ADOChangeSchema GetDefaultSchema(), "mySchema", .ItemData(i1) 'Not providing this one as it's not part of normal upscaling
'Set the primary key in SQL server
ADOAddPrimaryKey GetDefaultSchema(), .ItemData(i1), GetPKName(td)
'Create a new linked table, linking to the remote table
Set NewTd = db.CreateTableDef(.ItemData(i1), 0, GetDefaultSchema() & .ItemData(i1), conStr)
db.TableDefs.Append NewTd
Next i1
End With
End Sub
还有一些辅助功能:
Public Sub ADOAddPrimaryKey(SchemaName As String, tableName As String, FieldName As String)
On Error GoTo SetNotNull
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
Dim cmd As Object
Set cmd = CreateObject("ADODB.Command")
conn.Open adoString
cmd.ActiveConnection = conn
cmd.CommandText = "ALTER TABLE " & SchemaName & ".[" & tableName & "] ADD CONSTRAINT [" & tableName & "_PK] PRIMARY KEY CLUSTERED([" & FieldName & "]);"
cmd.Execute
Exit Sub
SetNotNull:
If Err.Number = -2147217900 Then
cmd.CommandText = "ALTER TABLE " & SchemaName & ".[" & tableName & "] ALTER COLUMN [" & FieldName & "] INTEGER NOT NULL"
cmd.Execute
cmd.CommandText = "ALTER TABLE " & SchemaName & ".[" & tableName & "] ADD CONSTRAINT [" & tableName & "_PK] PRIMARY KEY CLUSTERED([" & FieldName & "]);"
cmd.Execute
Else
Err.Raise Err.Number
End If
End Sub
Public Function GetDefaultSchema() As String
Dim conn As Object
Set conn = CreateObject("ADODB.Connection")
Dim rs As Object
conn.Open adoString
Set rs = conn.Execute("SELECT SCHEMA_NAME()")
GetDefaultSchema = rs.Fields(0)
End Function
Public Function GetPKName(td As DAO.TableDef) As String
'Returns the name of the first field included in the primary key (WARNING! Doesn't return all fields for composite primary keys!)
Dim idx As DAO.Index
For Each idx In td.Indexes
If idx.Primary Then
GetPKName = idx.Fields(0).NAME
Exit Function
End If
Next idx
End Function
这种形式只保留了数据和主键,做了几个假设(懒得回避了),比如:表名不包含方括号,没有复合主键,表模式在SQL中使用是安全的声明,没有附件字段或多值字段,也没有关系(有一个保留关系的版本,但是......老实说,我不知道它现在在哪里)。
它还会留下本地表的重命名副本。原始版本然后测试 1K 随机行以检查内容是否相同,但为简洁起见,我省略了它。
您可以将此作为起点,因为它可能需要调整以满足您的特定需求。