Модификация временной таблицы из приложения.

AnKa
Дата: 19.01.2001 12:48:51
MS SQL 7.0 + ADO Delphi5
Ну, ОООЧЕНЬ большая необходимость в сабже!
В общем, чего делаю:

1. Создал сторедпроку на сервере
CREATE PROCEDURE Proc1 AS
SELECT *
INTO #Tmp1
FROM Tab1

SELECT *
FROM #Tmp1

2. С помощью ADOStoredProc.Open вызываю ее из приложения Delphi.
УПС!!! Набор-то возвращается, только он не редактируемый . А очень надо!

Не подскажите ли выход из данной ситуации?

Заранее спа!
Oleg F
Дата: 19.01.2001 13:16:28
А почему обязательно для этого хранимую процедуру использовать, из принципа что-ли?
Почему просто нельзя запрос использовать?
SergSuper
Дата: 19.01.2001 13:45:53
Честно говоря непонятно чего же хочет автор вопроса.

1. Если временная таблица создается в процедуре, то она после завершения процедуры автоматически уничтожается.

2. Набор возвращаемый из процедуры - просто некий набор данных и некакой разницы нет будет сделан ли он из временной или постоянной таблицы, либо вообще не из таблиц.

3. Если хочется просто редактировать некий абстрактный набор - то снандартными методами через ADO в Delhi это не сделать.
AnKa
Дата: 19.01.2001 13:47:53
Ответ "Oleg F"`у.

Сторедпрока действительно нужна. Я написал поросто упрощенный вариант. А так там создается ВРЕМЕННЫЙ набор данных, который юзверь редактирует на форме, а потом, в зависимости от того, что он там наваял, данные ложаться определенным образом в базу.
Oleg F
Дата: 19.01.2001 13:57:52
Вот только зачем в этой хранимой процедуре таблицу создавать и зачем из неё набор возвращать.
В данном случае временная процедура должна просто заполнить временную таблицу данными, и всё.
А создание временной таблицы и последующий SELECT из неё с возможностью редактирования нужно сделать ВНЕ хранимой процедуры.
Конечно, я понимаю, что хочется из Delphi один запрос послать, а не три. Но если хочется редактировать временную таблицу, придётся всё-таки три запроса послать.
1) Создание временной таблицы
2) Вызов хранимой процедуры, которая эту таблицу заполняет
3) SELECT из временной таблицы, возвращающий "живой" набор с возможностью редактирования пользователем

Просто я такие вещи делал неоднократно, только не через ADO компоненты, а через обычный TQuery.
Единственное, чего нельзя делать, это такую вещь:

BEGIN TRANSACTION -- 1.
CREATE TABLE #T .... -- 2.
-- какие-то действия
-- какие-то действия
--
COMMIT TRANSACTION -- 3.

Тут проблема в том, что в промежуток времени от точки 1. до 3. никто не сможет работать с базой tempdb (т.е. она блокируется целиком).
AnKa
Дата: 19.01.2001 14:23:59
Фух, спешу похвастаться . Решил я таки эту проблемку таким образом:

CREATE PROCEDURE Proc1(@AUser char(20))
AS
IF not Exists (select *
from tempdb..sysobjects
where name='##Tmp1')

SELECT USER_LOGIN=@AUser,*
INTO ##Tmp1
FROM Tab1

ELSE

BEGIN
DELETE FROM ##Tmp1
WHERE USER_LOGIN=@AUser

INSERT INTO ##Tmp1
SELECT USER_LOGIN=@AUser,*
FROM Tab1
END

SELECT *
FROM ##Tmp1
WHERE USER_LOGIN=@AUser

Корявенько, конечно, уникальность набора в пределах базы обеспечивается логином пользователя, но это в моей ситуации вполне приемлемо. Можно вместо логина использовать @@SPID, надо подумать.... .Зато возвращается редактируемый набор и редактируй, как хошь . А потом юзверь нажимает кнопарик "Хочу!!!" и данные ложаться в базу. Я использовал именно ВРЕМЕННУЮ таблицу (##) вместо обыкновенной из-за желания незахламлять базу. Потому что необходимость в ней (таблице) будет возникать довольно редко.

В любом случае всем АГРОМНОЕ СПАСИБО! Согласитесь, тема довольно интересная.

ЗЫ. Дабы прояснить ситуацию: вместо
"SELECT USER_LOGIN=@AUser,* INTO ##Tmp1 FROM Tab1"
у меня идет выборка из 5 таблиц c разными наворотами а-ля UNION, JOIN и т.д.
alexeyvg
Дата: 19.01.2001 20:22:52
Классическое решение для таких задач:

1.Создать процедуру на сервере
CREATE PROCEDURE Proc1
AS
insert #Tmp1 (...)
SELECT ...
FROM Tab1

...
...

SELECT *
FROM #Tmp1

2. Создать из клиента врем. таблицу на сервере
create table #Tmp1(...)

3. и вызвать ту процедуру.
Garya
Дата: 23.01.2001 21:43:52
Вообще-то именно ADO предоставляет очень удобные средства для буферизации изменений. Только не на сервере, а на клиенте. И два варианта буферизации.
Вариант 1. С помощью метода SaveToFile (имеется только у ADO-компонентов в Delphi) можно сохранить текущее содержимое Dataset в обычный файл на клиенте, разорвать соединение с срвером, открыть полученный файл и править-править-править... Когда юзер будет удовлетворен результатами полученной работы, можно сбосить содержимое полученного файла через ADO-компонент обратно в базу.
Вариант 2. После того, как данные скачались в клиентский курсор, можно просто разорвать соединение с сервером, и править данные просто в локальном курсоре. При восстановлении соединения выполнить ButchUpdate - все сделанные изменения будут переданы на сервер одним махом. Для того, чтобы все сказанное стало возможным, нужно установить в правильные значения некоторые свойства, касающиеся пакетной обработки. Сейчас неохота лезть в книжки и поднимать все тонкости этого процесса. Тем более, что в Delphi я лично так делать не прбовал. Однако, в проектах Access-2000 через ADO я такие штуки проделывал - все нормально работает.