0

我正在尝试使用 Access 的升迁向导将数据从 Access 移动到 SQL Server。我目前遇到此错误,但无法弄清楚该属性的来源;

Property 'Attributes' already exists for 'table'.

它试图运行的 SQL 是;

EXEC sp_addextendedproperty N'Attributes', N'2', N'user', N'dbo', N'table', N'table', N'column', N'ID'

但是 Access 中的表不包含 ID 列,并且我在表的属性中看不到任何内容来表明它为什么要尝试为 SQL Server 添加属性。

在向导指南中,我选择不导入任何额外的东西,如索引、触发器等。

任何想法为什么向导会这样做以及如何阻止它尝试创建属性?

或者,是否有任何其他工具可以将数据从 Access 移动到 MSSQL,同时保持 Access 前端对象就位并正常工作?

4

1 回答 1

2

升迁向导从一开始就存在缺陷,并且已从最新版本的 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 随机行以检查内容是否相同,但为简洁起见,我省略了它。

您可以将此作为起点,因为它可能需要调整以满足您的特定需求。

于 2020-02-27T12:47:49.683 回答