Получить рекордсет из временной таблицы

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Получить рекордсет из временной таблицы

Сообщение VVitafresh » 13.12.2005 (Вт) 13:25

Как в VB можно получить рекордсет, выполнив последовательность SQL операторов типа:
Код: Выделить всё

create table #tmp(       
  acc char(14),
  ost decimal(15,2) null,       
    )

insert into #tmp (acc, ost)
(select acc, ost 
from table1,table3
where key1=key3, ...
UNION
select acc,  ost 
from table2,table3
where key2=key3, ...
)

select acc, sum(ost) from #tmp
group by acc

drop table #tmp


SQL операторы будут генерится из кода, поэтому хранимые процедуры использовать не получится. Таблица #tmp – временная, служит для накопления результатов и существует только во время текущего подключения к БД.

Пробую через Set rs = cnn.Execute(SQL) – рекордсет не возвращается, хотя и ошибок никаких не выдает.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 13:35

##tmp создавай

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 13.12.2005 (Вт) 14:42

Konst_One писал(а):##tmp создавай


Да нет проблема не в этом, даже если просто tmp назову SQL нормально отрабатывает таблица создается и заполняется, но
Код: Выделить всё

Set rs = cnn.Execute(SQL)

рекордсет не возвращает. При любом обращении к рекордсету, например rs.MoveFirst, пишет "Run time error 3704. Operation is not allowed when the object is closed"

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 14:51

SQL - в студию :!:

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 14:52

создать одним скриптом, выполнить селект другим, дропнуть третьим - вот такая последовательность :!:

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 13.12.2005 (Вт) 14:53

См. Help по SET NOCOUNT ON

Или юзай NextRecordset :lol:
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 15:00

Andrey Fedorov
тоже верно

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 13.12.2005 (Вт) 16:18

Konst_One писал(а):создать одним скриптом, выполнить селект другим, дропнуть третьим - вот такая последовательность :!:

Так в общем то работает. Только возникает попутный вопрос: временная таблица #tmp будет уникальной для каждого отдельного пользователя при одновременной работе юзеров, конфликты не возникнут? И еще: В ПРИНЦИПЕ приведенная мной выше последовательность SQL (без дробления) должна возвращать рекордсет в VB или нет(при выполнении через утилиты сервера рекордсет возвращается)?

Andrey Fedorov писал(а):См. Help по SET NOCOUNT ON Или юзай NextRecordset

SET NOCOUNT ON не помогает, а с NextRecordset еще не работал -- попробую.

P.S. Забыл с самого начала уточнить SQL сервер у меня Sybase Adaptive Server Enterprise 12.5, хотя возможно это и не принципиально, синтаксис Transact-SQL очень сходен с MS SQL.

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 16:43

#tmp - сессионая, поэтому будет видна в пределах одной открытой сессии, если нужно, чтобы временная таблица была видна в других сессиях, то делай ##tmp

на счет sybase не в курсе, но вроде бы там все очень похоже на сиквел

Код: Выделить всё
SET NOCOUNT ON

CREATE TABLE #tmp(       
  acc char(14),
  ost decimal(15,2) NULL,       
    )

INSERT INTO #tmp (acc, ost)
(SELECT acc, ost 
FROM table1,table3
WHERE key1=key3, ...
UNION
SELECT acc,  ost 
FROM table2,table3
WHERE key2=key3, ...
)

SET NOCOUNT OFF

SELECT acc, sum(ost) FROM #tmp
GROUP BY acc

DROP TABLE #tmp

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 13.12.2005 (Вт) 17:05

Видимость #tmp в пределах сессии -- как раз то, что мне нужно, спасибо за разъяснение.

А вот SET NOCOUNT ON ну никак не помогает (возможно на Sybase он не производит впечатления). Рекордсет возвращается только, если SELECT... является единственной командой при выполнении Set rs = cnn.Execute(SQL) :(

Konst_One
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
Аватара пользователя
 
Сообщения: 3041
Зарегистрирован: 09.04.2004 (Пт) 13:47
Откуда: Химки

Сообщение Konst_One » 13.12.2005 (Вт) 17:27

попробуй убрать из скрипта : DROP TABLE #tmp

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 13.12.2005 (Вт) 17:55

Это я первым делом пробовал -- не помогает.
Ну и фиг с ним, этим запросом. Главное, что в пределах сессии с временной таблицей можно работать, а из других сессий её не видно. Причем дропать даже не обязательно, таблица создается в tempdb и сама удаляется при закрытии соединения. А дробить запрос меня в общем то не сильно напрягает.
Спасибо за помощь!

Andrey Fedorov
Член-корреспондент академии VBStreets
Член-корреспондент академии VBStreets
 
Сообщения: 3287
Зарегистрирован: 21.05.2004 (Пт) 9:28
Откуда: Москва

Сообщение Andrey Fedorov » 16.12.2005 (Пт) 8:49

VVitafresh писал(а):SET NOCOUNT ON не помогает, а с NextRecordset еще не работал -- попробую.


По MS SQL помог бы.

Если говорить о конкретном примере то в нем можно вообще обойтись без временной таблицы - все делается одним запросом.

А если вообще, то таблицу можно объявлять еще как

DECLARE @t TABLE(...)

чтобы не заморачиваться со временными. Но это имеет свои недостатки...
Да и от SET NOCOUNT ON все одно не отвертеться - опять же под MS SQL. С Sybase я не работал, потому точно по нему не скажу.
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...

VVitafresh
Продвинутый гуру
Продвинутый гуру
Аватара пользователя
 
Сообщения: 1641
Зарегистрирован: 12.05.2005 (Чт) 14:44
Откуда: Херсон, UA

Сообщение VVitafresh » 16.12.2005 (Пт) 16:21

По мануалам Sybase тоже вроде бы должен помочь:
nocount
Указывает, будет ли отображаться количество строк, обработанных
командой. Установка set nocount on отключает отображение коли-
чества строк, а set nocount off – включает.

Реально от установки SET NOCOUNT ON ничего не меняется (в моем случае).

А насчет примера: я его специально упростил, чтобы сосредоточить внимание на сути проблемы, реально запрос сложнее -- на начальном этапе производится агрегирование нескольких таблиц, затем объединение результатов, потом связывание с еще одной таблицей. Причем, если все это слепить в один запрос, то намного увеличится время обработки.
Но как я уже писал, меня вполне устроил вариант работы с временной таблицей отдельными запросами. Не вижу в этом никакой проблемы.


Вернуться в Базы данных

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

    TopList  
cron