Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Microsoft Office и VBA программирование > Microsoft Office Access
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.06.2010, 23:38   #1
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию ADODB Connection, RecordSet и временные таблицы

Вечер добрый!

Есть пара вопросов, не могу разобраться.

1) У меня есть БД - файл .mdb в котором содержатся только таблицы, расположен на сетевом диске общего доступа (пусть будет 1.mdb). Создается другой файл .mdb (который после завершения разработки будет конвертирован в .mde и разослан пользователям для работы, в данный момент 2.mdb). В нем для передачи и получения данных устанавливается связь с БД, в которой таблице, с помощью ADO. Чтобы постоянно не работать с данными через сеть, предполагается сначала вытянуть из исходной БД все нужные таблицы (справочники), а затем, работая уже с ними как с локальными, передавать конечные данные в сетевую базу.
Для определенности назовем таблицу-справочник main, а временную таблицу, в которую импортируем данные, - tmp, текущее соединение - cn.
Если воспользоваться процедурой:
Код:
cn.Execute "SELECT * INTO tmp FROM main"
То все будет хорошо, но временная таблица создастся в файле 1.mdb.

Следующий код не приводит ни к чему:
Код:
cn.Execute "SELECT * INTO tmp IN {полный путь к файлу 2.mdb} FROM main"
Вопрос: что не так?

2) Если напрямую никак, то приходит на ум мысль перекидывать через RecordSet. Тогда вопрос в следующем: каков порядок действий?
Открыть соединение, открыть рекордсет, закрыть соединение, забить "построчно" временную таблицу, используя CurrentDb.Execute?

Бонус: есть способ в одно действие перекинуть рекордсет в таблицу или только через цикл по записям?

Всем заранее спасибо!
AdrenalinE вне форума Ответить с цитированием
Старый 22.06.2010, 01:11   #2
Teslenko_EA
Участник клуба
 
Регистрация: 10.08.2009
Сообщений: 1,796
По умолчанию

Здравствуйте AdrenalinE.
Судя по фразам "..файл .mdb в котором содержатся только таблицы, расположен на сетевом диске.." и "..предполагается.. вытянуть из исходной БД .." - "cn.Execute ...." должно выполняется в клиентском приложении.
1. cn.Execute "SELECT * INTO tmp FROM main" - однозначно выполняется только в одной БД к которой выполнено подключение. Прилинковав к "клиентской" БД (2.mdb), таблицу сетевой БД (1.MDB) эта конструкция будет выполняться на стороне клиента и с применением DAO:
CurrentDB.Execute "SELECT * INTO tmp FROM main"
соответственно вторая SQL конструкция:
"SELECT * INTO tmp IN {полный путь к файлу 2.mdb} FROM main"
тоже должна быть работоспособна на стороне клиента если её видоизменить подобным образом:
"SELECT * INTO tmp FROM main IN {полный путь к файлу 1.mdb}"
Первый вариант подразумевает присутствие в БД прилинкованой таблицы, но если обращение к ней будет не постоянным, нагрузки на сеть не будет, в любом случае выбор варианта за автором.

2. "..порядок действий.." - Открыть соединение, открыть рекордсет, забить "построчно" временную таблицу, закрыть рекордсет, закрыть соединение.

"..есть способ в одно действие перекинуть рекордсет в таблицу.." только в таблицу листа Excel применяя ADO,
"..или только через цикл по записям.." - печально, но таблицам БД без перебора рекордсета не обойтись.

Евгений.
Teslenko_EA вне форума Ответить с цитированием
Старый 22.06.2010, 08:14   #3
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию

Евгений, в очередной раз премного благодарен! Необходимо снизить нагрузку на сеть и повысить скорость обработки запросов, поэтому решил покопаться поглубже в Access и запутался. Теперь вроде бы все ясно, буду пробовать.
AdrenalinE вне форума Ответить с цитированием
Старый 22.06.2010, 19:44   #4
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию

Как все интересно оказалось.
Код:
cn.Execute "SELECT * INTO tmp IN {полный путь к файлу 2.mdb} FROM main"
Работает нормально, но таблица не видна, пока вручную не нажать F5 в списке таблиц. При этом и базой она не определяется, т.е. при попытке
Код:
DROP TABLE tmp
пишет ошибку, что такой таблицы не существует. Кто знает, как программно обновить список таблиц в базе?
AdrenalinE вне форума Ответить с цитированием
Старый 22.06.2010, 19:57   #5
Teslenko_EA
Участник клуба
 
Регистрация: 10.08.2009
Сообщений: 1,796
По умолчанию

Рекомендую почитать о команде RefreshDatabaseWindow, думаю она Вам будет полезна.
Евгений.
Teslenko_EA вне форума Ответить с цитированием
Старый 22.06.2010, 20:03   #6
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию

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

update: хотя вопрос пока что отменяется, у меня там обработчик ошибок, возможно, не в том месте. Так что завтра проверю, может и работает этот метод.

Последний раз редактировалось AdrenalinE; 22.06.2010 в 22:06.
AdrenalinE вне форума Ответить с цитированием
Старый 22.06.2010, 22:07   #7
Teslenko_EA
Участник клуба
 
Регистрация: 10.08.2009
Сообщений: 1,796
По умолчанию

Судя по SQL конструкции "... IN {полный путь к файлу 2.mdb} FROM main" она выполняется в "серверном" файле БД (1.mdb), я уже обращал Ваше внимание, что результат будет лучше если "..эта конструкция будет выполняться на стороне клиента..", во всяком случае запускаться в клиентском приложении.
также на стороне клиента может быть выполнена команда - CurrentDb.TableDefs.Refresh
и RefreshDatabaseWindow выполняемая в клиентской БД (2.mdb), должна отображать ("перерисовывать") все изменения в объектах БД.
надеюсь у Вас всё получится.
Евгений.
Teslenko_EA вне форума Ответить с цитированием
Старый 22.06.2010, 22:44   #8
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию

Евгений, спасибо за советы.

До меня только что дошло, в чем коренное отличие конструкции:
Код:
"SELECT * INTO tmp FROM main IN {полный путь к файлу 1.mdb}"
Таким образом можно не устанавливать соединение, а просто выполнить SQL-код через DAO?
Код:
CurrentDb.Execute "SELECT * INTO tmp FROM main IN {полный путь к файлу 1.mdb}"
На сегодня это последний вопрос. Была бы база под рукой, уже бы попробовал 200 раз, но приходится интуитивно набирать пищу для размышлений на завтра.
AdrenalinE вне форума Ответить с цитированием
Старый 23.06.2010, 20:22   #9
AdrenalinE
Пользователь
 
Аватар для AdrenalinE
 
Регистрация: 29.09.2007
Сообщений: 95
По умолчанию

Точно, обработчик ошибки не там стоял, все отлично работает с RefreshDatabaseWindow.

И с прямым вытягиванием данных через
Код:
CurrentDb.Execute "SELECT * INTO tmp FROM main IN {полный путь к файлу 1.mdb}"
Тогда не понимаю, зачем вообще бывает нужно устанавливать связь с источником данных? Чтобы подключаться к БД, требующим авторизации?
AdrenalinE вне форума Ответить с цитированием
Старый 23.06.2010, 20:39   #10
Teslenko_EA
Участник клуба
 
Регистрация: 10.08.2009
Сообщений: 1,796
По умолчанию

Здравствуйте AdrenalinE.
"..Тогда не понимаю, зачем вообще бывает нужно устанавливать связь.."
и действительно зачем паровоз если и велосипед едет.
они в разных "весовых категориях".
Евгений.
Teslenko_EA вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
временные функции Assemblerru Общие вопросы C/C++ 2 04.04.2010 12:43
не создать набор запесей (ADODB.Recordset) МаМи Microsoft Office Access 1 22.02.2010 11:19
Работа с объектом ADODB.Stream voam Microsoft Office Excel 4 15.12.2009 23:31
Adodb+smarty проблема с циклом while Oleg_453 PHP 2 02.12.2008 14:41
Временные задержки dgoc Помощь студентам 1 05.12.2007 05:03