Как я могу связать Access tabledef с временной таблицей в SQLServer

#sql-server #ms-access

#sql-сервер #ms-access

Вопрос:

Я переношу интерфейсное / серверное приложение MS Access на серверный интерфейс MS Access / sql server.

Одна часть этого приложения (в оригинальной форме) использует VB для импорта CSV-файла в таблицу во внешнем интерфейсе, а затем выполняет различные инструкции SQL для объединения содержимого этой таблицы в некоторые внутренние таблицы.

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

  1. Откройте соединение с серверной частью
  2. Создайте временную таблицу в этом соединении
  3. Создайте tabledef в VB и попытайтесь подключить его к этой временной таблице
  4. Используйте DoCmd.TransferText (как я делаю в оригинале) для импорта CSV-файла в таблицу, на которую ссылается таблица def
  5. Выполните хранимую процедуру в открытом соединении, которая объединяет данные временной таблицы с постоянными таблицами на серверной части.

Я думаю, что успешно выполняю шаги 1 и 2, но я не уверен. Я могу видеть временную таблицу в SQL Server Management Studio, но попытка открыть столбцы завершается ошибкой (она также завершается с той же ошибкой, когда я использую Management Studio для создания временной таблицы, поэтому я думаю, что это проблема Management Studio).

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

Код, который я использую для этого, выглядит следующим образом

     Set conn = New ADODB.Connection
    conn.Open getStrConn

    'First create a temporary table on the server for the web site leads
    SQL = "CREATE TABLE [dbo].[#WebSiteLeads]("
    SQL = SQL amp; "[leadID] [int] IDENTITY(1,1) PRIMARY KEY CLUSTERED,[Title] [nvarchar](255) NULL,[Firstname] [nvarchar](50) NULL,"
    SQL = SQL amp; "[Lastname] [nvarchar](50) NULL,[Sex] [nvarchar](10) NULL,[House] [nvarchar](50) NULL,"
    SQL = SQL amp; "[Address1] [nvarchar](50) NULL,[Address2] [nvarchar](50) NULL,[Street] [nvarchar](50) NULL,"
    SQL = SQL amp; "[Town_City] [nvarchar](50) NULL,[County] [nvarchar](50) NULL,[Postcode] [nvarchar](10) NULL,"
    SQL = SQL amp; "[Email] [nvarchar](50) NULL,[Allow_email] [nvarchar](5) NULL,[Telephone] [nvarchar](20) NULL,"
    SQL = SQL amp; "[Allow_tel] [nvarchar](5) NULL,[Cons_period] [nvarchar](20) NULL,[When] [nvarchar](20) NULL,"
    SQL = SQL amp; "[Procedure] [nvarchar](20) NULL,[Consultation] [nvarchar](10) NULL,[Info_pack] [nvarchar](10) NULL,"
    SQL = SQL amp; "[Source] [nvarchar](20) NULL,[Further_info] [nvarchar](255) NULL,[Callback] [nvarchar](50) NULL,"
    SQL = SQL amp; "[Date_added] [nvarchar](30) NULL,[Date_added_dt] [datetime] NULL,[Callback_range] [tinyint] NULL,"
    SQL = SQL amp; "[UcFname] [nvarchar](1) NULL,[UcLname] [nvarchar](50) NULL,[UcPcode] [nvarchar](10) NULL);"

    conn.Execute SQL

    For Each td In CurrentDb.TableDefs
        If td.name = "WebsiteLeads" Then
            CurrentDb.TableDefs.Delete "WebsiteLeads"
        End If
    Next
    'link to the table just created
    Set td = CurrentDb.CreateTableDef("WebsiteLeads",dbAttachSavePWD , "[dbo].[#WebSiteLeads]", getStrConn)

    CurrentDb.TableDefs.Append td
    importProgress = 0.1    'Update Progress bar
    DoEvents

    'Import our text file
    DoCmd.TransferText acImportDelim, "Leads Import v2", "WebsiteLeads", txtFileName
    importProgress = 0.3    'Update Progress bar
    DoEvents

    'We are going to do the rest as Access stored procedure

    Set leadsRS = conn.Execute("EXEC dbo.LeadsImport;")
    importProgress = 0.9    'Update Progress bar
    DoEvents
  

Но это не удается на

         CurrentDb.TableDefs.Append td
  

с сообщением об ошибке «Не удалось найти устанавливаемый ISAM».

Что это за сообщение об ошибке и почему я его получаю

Комментарии:

1. Обязательно ли это должна быть временная таблица на SQL Server? Мне кажется, вы каждый раз создаете temp с одной и той же структурой. Вы могли бы просто очищать ее при каждом запуске sp. Вы можете связать с обычной таблицей SQL Server просто отлично, не так ли?

2. Я думаю, вы застряли. Я не знаю ни о каком способе ссылки на временную таблицу. Однако в предыдущем комментарии у HansUp есть хороший обходной путь — создайте постоянную таблицу (структуру) в SQL Server и обработайте ее содержимое как временное, заставив SP обрезать его непосредственно перед импортом (если ваш администратор базы данных не предоставит вам разрешения, необходимые для усечения, вам придется довольствоваться удалением).

3. Я нашел способ обойти проблему — я думаю. Основная причина, по которой я использовал временную таблицу, заключается в том, что если два пользователя импортируют одновременно, они могут споткнуться друг о друга. Временная таблица эффективно предоставляет отдельное пространство имен каждому пользователю. Но если я оберну все это в транзакцию begin .. commit, я могу получить это разделение с помощью процессов транзакции

4. Я забыл в приведенном выше сказать, что таблица, которую я использую, может быть постоянной, как предложил ХансУп.

5. Рассматривали ли вы возможность создания временной таблицы локально, на рабочей станции, и использования Jet / ACE MDB / ACCDB, хранящейся на рабочей станции, для временной таблицы? В этом случае имя таблицы всегда будет одинаковым, но оно всегда будет специфичным для каждого пользователя.

Ответ №1:

Другой альтернативой было бы вообще не использовать связанную таблицу, а вместо этого использовать сквозной запрос, который возвращает временную таблицу. Скорее всего, вам придется писать это на лету, но как только он вернет правильную временную таблицу, ее можно использовать в качестве источника записи формы или отчета.

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

Комментарии:

1. Интересно — хотя я не уверен, что это сработает — камнем преткновения является DoCmd. TransferText, для которого требуется имя таблицы. Из ссылки «Строковое выражение, являющееся именем таблицы Microsoft Access, в которую вы хотите импортировать текстовые данные, экспортировать текстовые данные или связать текстовые данные с запросом Microsoft Access, результаты которого вы хотите экспортировать в текстовый файл». который разрешает запрос только при экспорте. Я нашел обходной путь (см. Комментарий выше), поэтому использую его. Позже сегодня я буду изучать сквозные запросы путем динамического создания querydef, вызывающего хранимую процедуру

2. Если вы пишете сохраненный запрос, DoCmd. TransferText вообще не используется. В этом вся моя суть — вы полностью избегаете проблемы. Короче говоря, вы, кажется, пропустили весь смысл моего ответа.

3. Я либо что-то упускаю, либо, возможно, вы не совсем понимаете, что я делаю. DoCmd. TransferText передает, используя спецификацию во внешнем интерфейсе, файл CSV, загруженный локально на компьютере, на котором запущен внешний интерфейс, в таблицу, о которой мы говорим. Если я не попытаюсь проанализировать этот файл программно, TransferText кажется единственным способом загрузить его в таблицу.

4. И я хочу сказать, что ВАМ НЕ НУЖНА ТАБЛИЦА — запрос может выполнить эту работу (ПРЕДСТАВЛЕНИЕ). Вы можете написать QueryDef «на лету» по мере необходимости, и вам не нужно беспокоиться о наличии постоянной связанной таблицы. Единственная причина, по которой вам нужно сохранить QueryDef (в отличие от назначения SQL SELECT в качестве источника записей / источника строк объекту Access), заключается в том, что вам нужно использовать сквозной переход, чтобы иметь полный доступ к временным таблицам.

5. ! Загорается индикатор — я понимаю, что вы сейчас говорите! Извините, я был тупым. Я только что создал пассивный запрос для другой части приложения, которая вызывает хранимую процедуру для использования в качестве источника данных для отчета. Пришлось немного повозиться, чтобы перейти от соединения ADO к DAO. QueryDef (см. chandlerfamily.org.uk/2011/05 / … )