Как добавить данные из таблицы SQL Server в таблицу доступа - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь выяснить, как написать запрос в MS Access, который откроет соединение с локальным SQL Server, а затем позволит мне импортировать выбранные таблицы в MS Access.

Я вставлю копию моего кода ниже. Пожалуйста, дайте мне знать, как исправить. Кажется, он работает до оператора Cn.Execute. Я получаю

Ошибка времени выполнения '-2471765 (80040e37)' [Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Недопустимое имя объекта 'dbo_SQLServertable'.

Потребуется также импортировать дополнительные таблицы, поэтому мне нужен код, который будет работать, когда я смогу изменить имена таблиц.

Private Sub Command28_Click()


 Dim Cn As ADODB.Connection
    Dim Server_Name As String
    Dim Database_Name As String
    Dim User_ID As String
    Dim Password As String
    Dim SQLStr As String
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset

    Server_Name = "" ' Enter your server name here
    Database_Name = "Test" ' Enter your database name here
    User_ID = "" ' enter your user ID here
    Password = "" ' Enter your password here

    Set Cn = New ADODB.Connection
    Cn.Open "Driver={SQL Server};Server=" & Server_Name & ";Database=" & Database_Name & ";"

    Cn.Execute "INSERT INTO Access Table SELECT dbo_SQLServerTable.* FROM dbo_SQLServerTable;"

    Set rs = Nothing
    Cn.Close
    Set Cn = Nothing

***** ОБНОВЛЕНИЕ ***** Привет всем, спасибо за ответы до сих пор. Они все помогали. Я сделал некоторые обновления, и теперь я получаю новое сообщение об ошибке

Ошибка времени выполнения '-2147216900 (80040e14)' [Microsoft] [Драйвер ODBC SQL Server] [SQL Server] Невозможно вставить значение NULL в столбец «DiagnosisOrdinal», таблица «Office.dbo.Test» не позволяет обнуляет. Вставить не удалось.

Похоже, что мой оператор вставки все еще ссылается (или пытается ссылаться) на таблицу на сервере SQL. «Офис» - это имя базы данных, из которой я извлекаю данные.

Должен ли я закрыть соединение и затем вставить данные в мою локальную таблицу доступа? Придется ли мне снова открывать и закрывать соединение, если я хочу сделать это для нескольких таблиц?

Я изменил свой оператор execute с

Cn.Execute "Вставить в таблицу доступа SELECT dbo_SQLServerTable. * FROM dbo_SQLServerTable;"

до

Cn.Execute "INSERT INTO Test (VisitID, Provider) SELECT VisitID, Provider FROM dbo.SQLServerTable;"

Еще раз спасибо за вашу помощь. Мы близко!

Ответы [ 4 ]

0 голосов
/ 18 января 2019

Наименьшее количество кода, которое я могу придумать, - это использовать сквозной запрос.

Настройка запроса PT для рассматриваемой базы данных сервера.

Тогда ваш код для создания новой таблицы в доступе будет выглядеть так:

Sub TestImport()

  Dim strSQL     As String

  With CurrentDb.QueryDefs("qryPassR")
     .SQL = "select * from tblHotels"
  End With

  Dim strLocalTable  As String

  strLocalTable = "zoo"

  CurrentDb.Execute "select * into " & strLocalTable & " FROM qryPassR"

End Sub

Выше, конечно, предполагается, что вы создали соединение с сервером SQL (одна база данных), когда вы создали запрос PT. Приведенный выше подход хорош, поскольку вы не возитесь со строками соединения в коде.

Однако, если вам нужно (хотите) указать базу данных (и, скорее всего, сервер), то выше становится так:

Sub TestImport2()

  Dim strSQL           As String
  Dim strServer        As String
  Dim strDatabase      As String
  Dim strUser          As String
  Dim strPass          As String

  strServer = ""
  strDatabse = ""
  strUser = ""
  strPass = ""

  Dim strLocalTable       As String
  Dim strServerTable      As String

  With CurrentDb.QueryDefs("qryPassR")
     .Connect = dbCon(strServer, strDatabase, strUser, strPass)
     .SQL = "select * from " & strServerAble
  End With

  CurrentDb.Execute "select * into " & strLocalTable & " FROM qryPassR"

End Sub

Выше используется «удобная» функция для создания строки подключения.

Эта функция выглядит следующим образом:

Public Function dbCon(ServerName As String, _
                     DataBaseName As String, _
                     Optional UserID As String = "", _
                     Optional USERpw As String, _
                     Optional APP As String = "Office 2010", _
                     Optional WSID As String = "Import") As String

   ' returns a SQL server conneciton string

  dbCon = "ODBC;DRIVER=" & SQLDRIVER & ";" & _
          "SERVER=" & ServerName & ";" & _
          "DATABASE=" & DataBaseName & ";"
          If UserID <> "" Then
             dbCon = dbCon & "UID=" & UserID & ";" & "PWD=" & USERpw & ";"
          End If
          dbCon = dbCon & _
          "APP=" & APP & ";" & _
          "WSID=" & WSID & ";" & _
          "Network=DBMSSOCN"

End Function

Редактировать

Автор попросил найти решение для добавления данных в СУЩЕСТВУЮЩУЮ таблицу.

В этом случае просто измените это:

  CurrentDb.Execute "select * into " & strLocalTable & " FROM qryPassR"

К

  CurrentDb.Execute "INSERT INTO " & strLocalTable & " SELECT * FROM qeryPassR"
0 голосов
/ 18 января 2019

Есть несколько предложений по этому конкретному вопросу

  1. Пройти через запросы
  2. Связанные таблицы из SQL Server. Вам, вероятно, придется настроить файл DSN, что не слишком сложно.
  3. Или обработайте это напрямую в SQL Server Вставьте в Access из SQL Server
  4. ODBC-соединение через VBA (то, что вы делаете и, казалось бы, самое запутанное)

Все эти подходы будут работать нормально. Я предлагаю связанные таблицы, чтобы вы не дублировали данные, но для вас это чушь, так как я не знаю требований проекта.

0 голосов
/ 18 января 2019

dbo_SQLServerTable - это имя таблицы Access, а не имя таблицы SQL-сервера. Поскольку вы уже создали связанную таблицу dbo_SQLServerTable, вы можете использовать следующий код VBA.

Currentproject.connection.execute "INSERT INTO MyAccessTable(fld1, fld2, fld3) SELECT fld1, fld2,fld3 FROM dbo_SQLServerTable"

Нет необходимости создавать объект подключения в коде VBA. Currentproject.connection всегда доступен для ссылки.

0 голосов
/ 18 января 2019

Вам не нужен префикс таблицы в вашем SELECT из таблицы SQL. Просто сделайте SELECT * FROM dbo_SQLServerTable; Однако лучше не использовать SELECT *, а указывать столбцы на случай, если схемы таблиц изменятся.

...