Увеличение доступа - свойство 'Атрибуты' уже существует для 'таблицы'
Я пытаюсь использовать мастер увеличения размера 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 не включает столбец идентификатора, и я не вижу ничего в свойствах таблицы, чтобы указать, почему он пытается добавить свойство для SQL Server.
В руководстве мастера я решил не импортировать дополнительные функции, такие как индексы, триггеры и т. Д.
Есть идеи, почему мастер делает это и как остановить его попытки создать свойства?
В качестве альтернативы, существуют ли какие-либо другие инструменты, которые могли бы перемещать данные из Access в MSSQL, сохраняя при этом внешние объекты Access на месте и работающими?
1 ответ
У мастера увеличения размера были свои недостатки с самого начала, и он был удален из последних версий Access. Рекомендую не использовать.
Лично у меня есть форма, которая выполняет увеличение размера за меня. Это форма с двумя текстовыми полями с именемConStr
а также adoString
(первая содержит строку подключения для использования Access, включая ODBC;
префикс, второй содержит строку ODBC или OLEDB для использования ADO), кнопку с именем 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-сервер:
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 операторов, нет полей вложений или многозначных полей, и нет отношений (была версия, которая сохранила отношения, но... я, честно говоря, не знаю, где это сейчас).
Он также оставляет переименованную копию локальной таблицы. Исходная версия затем проверяет 1К случайных строк, чтобы проверить идентичность содержимого, но для краткости я опущен.
Вы можете использовать это как отправную точку, поскольку может потребоваться настройка в соответствии с вашими конкретными потребностями.