ADO и temporary table в MS SQL 2000

Работа VB и СУБД (Access, MSSQL, MySQL, Oracle и пр.)
Правила форума
При создании новой темы не забывайте указывать используемую СУБД.
valk
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 11.02.2002 (Пн) 18:09
Откуда: Ukraine

ADO и temporary table в MS SQL 2000

Сообщение valk » 24.05.2005 (Вт) 11:59

Здравствуй, All.
Наткнулся на такую граблю:
Надо мне работать с временной табличкой
Работаю с 1 соединением во всей проге

Public dbconnect As ADODB.Connection


Dim cmd as ADODB.Command
Set cmd = New ADODB.Command
cmd.ActiveConnection = dbconnect

cmd.CommandText = "create table #UserRights ( project int, rights tinyint)"
cmd.Execute

cmd.CommandText = "insert into #UserRights select pid, rights=7 from projects where otv=suser_sid()"
cmd.Execute

Все нормально, пока я не пытаюсь открыть рекордсет перед вставкой данных.
Как только добавляю строчку

Set rs = New Recordset
rs.ActiveConnection = dbconnect

rs.Open "select pid from projects where otv=suser_sid()" ', , adOpenStatic, adLockReadOnly

при попытке выполнить insert into ругается на #UserRights что нет такого объекта.

Это так надо? Или я где-то намудрил?

С уважением, Valk
valk

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 24.05.2005 (Вт) 12:23

Это не баг, это фича. Существуют 2 типа временных таблиц - локальные и глобальные. Локальные создаются с префиксом из одного шарпа в имени (как у тебя), а глобальные - с двумя. Время жизни локальных ограничено длительностью того батча, в котором они созданы, и видны они только тому коннекту, с которого их сделали. Глобальные (т.к. видны и доступны всем соединениям на сервере) живут до тех пор, пока не закроются все соединения, из которых были обращения к этой таблице.

В твоем случае времянка, судя по всему, автоуничтожается по окончании последнего Cmd.Execute :). Рекомендация - если работаешь с временными таблицами и при этом не хочется использовать глобальные (ибо в этом случае возможны конфликты их имен) - оформляй кусок серверного кода как единое целое и выноси его в хранимую процедуру, благо у MSSQL с этим проблем нет, в отличие от всяких прочих "тоже СУБД" (не будем показывать пальцем).

А вообще - BOL->Create Table, раздел Temporary tables. Вышеприведенный текст - не более чем краткий пересказ оного.

valk
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 11.02.2002 (Пн) 18:09
Откуда: Ukraine

Сообщение valk » 24.05.2005 (Вт) 13:42

Все так, но прикол в том, что оно у меня работало.
Поскольку я не закрывал соединение, можно было потом обращаться к времянке из любого места проги. И если не открывать рекордсет в запостеном примере, все прокатывает.
Рекордсет что, новый батч объявляет?
valk

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 24.05.2005 (Вт) 14:21

Трассу снимать пробовал? В смысле, вешать SQL Profiler на свой коннект? Скорее всего, драйвер какую-нить пургу гонит, типа
Код: Выделить всё
SET IMPLICIT_TRANSACTIONS ON
- ох и наелся я в свое время с этим барахлом. Шняга вроде незаметная, а исполнение запросов меняет радикально.

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

Сообщение Konst_One » 24.05.2005 (Вт) 14:43

можно и с одной решеткой юзать (#), но только , если всегда использовать один коннекшн:


Код: Выделить всё
...
Set cmd.ActiveConnection = dbconnect
...
Set rs.ActiveConnection = dbconnect
...

valk
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 11.02.2002 (Пн) 18:09
Откуда: Ukraine

Сообщение valk » 30.05.2005 (Пн) 13:22

Проверил SQL Profiler- ом
Когда открываю рекордсет в логах появляется куча строк “audit logon” и “audit logout”;
А когда идет только выполнение команд, все нормально, вход и выход 1 раз.
Это как-то лечится?
valk

Ennor
Конструктивный критик
Конструктивный критик
 
Сообщения: 2504
Зарегистрирован: 18.12.2001 (Вт) 3:58
Откуда: Калуга -> Москва

Сообщение Ennor » 30.05.2005 (Пн) 22:40

Погоди, ты имеешь в виду, что при выполнении вот этого:
Код: Выделить всё
select pid from projects where otv=suser_sid()
на рекордсете у тебя появляется куча коннектов/дисконнектов? Бред какой-то, ADO так себя не ведет, это тебе не JOnAS какой-нить...

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

Re: ADO и temporary table в MS SQL 2000

Сообщение Andrey Fedorov » 31.05.2005 (Вт) 10:19

valk писал(а):
Код: Выделить всё
cmd.CommandText = "create table #UserRights ( project int, rights tinyint)"
cmd.Execute

cmd.CommandText = "insert into #UserRights select pid, rights=7 from projects where otv=suser_sid()"
cmd.Execute


А нафига вообще такие танцы?

Если что-то очень хочется выполнить подобным образом с клиента, то лучше делать а-ля:

Код: Выделить всё
cmd.CommandText = "create table #UserRights ( project int, rights tinyint)" & vbcrlf _
    & "insert into #UserRights select pid, rights=7 from projects where otv=suser_sid()" & vbcrlf _
    & " и остальной серверный код"
cmd.Execute


А от временных таблиц я что-то давненько отошел - когда нужно то применяю:

Код: Выделить всё
DECLARE @t TABLE( ... )
Фиг Вам! - Сказал Чебурашка, обгладывая Крокодила Гену...


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

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

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

    TopList  
cron