-
Здравствуйте! Есть такая задача: нужно сохранить rtf файл в базу данных, затем из базы данных получить и загрузить в редактор. rtf передается в поток TMymoryStream. Для записи в базу данных используется хранимая процедура типа: @code image AS INSERT INTO temp_table(code) VALUES(@code) -----------------------------------------------------
var mystream:Tmemorystream; // сюда передаю rtf
Пользуюсь компонентом ADOCommand
ADOCommand1.CommandType:=cmdStoredProc; ADOCommand1.CommandText:='p_inferno_temp2;1'; ADOCommand1.Parameters.Clear; ADOCommand1.Parameters.Add; ADOCommand1.Parameters[0].Direction:=pdInput; ADOCommand1.Parameters[0].Name:='@code'; ADOCommand1.Parameters[0].LoadFromStream(mystream,ftBlob);
Параметру не передается значение из потока. такой вариант записи в базу вобще возможен?
-
with ADOCommand1 do
begin
Connection := ....;
CommandText := 'exec s_MyProc @code=:code';
Parameters.ParamByName('code').DataType := ftBlob;
Parameters.ParamByName('code').LoadFromStream(mystream,ftBlob);
try
Execute;
except
......
end;
end;
-
Это осилил, спасибо, а как теперь из базы выгрузить в stream?
-
with TADODataSet.Create(nil) do
begin
try
Connection := .....;
CommandText := 'Select code from temp_table';
try
Open;
if IsEmpty then Exit;
ms := TMemoryStream.Create;
try
TBLOBField(FieldByName('code')).SaveToStream(ms, ftBLOB);
ms.Position := 0;
... Работаем с ms
finally
ms.Free;
end;
except
.....
end;
finally
Free;
end;
end;
-
спасибо за оперативность :) пойду пробовать
-
Все работает. Теперь пытаюсь сделать вывод с помощью хранимой процедуры
если просто то: CREATE PROCEDURE temp_out AS select code from temp_table GO
В принципе я вызываю процедуру, она мне возвращает набор, и я его обрабатываю как описано выше... Так будет работать?
-
> Так будет работать? >
Да. Только я бы сделал такую процедуру: CREATE PROCEDURE s_temp_table
@ActNam varchar(32)='NONE',
@Code image =NULL
AS
Declare @result int;
Set NoCount On;
Set @ActNam=LTrim(RTrim(Upper(@ActNam)));
Set @result=0;
if @ActNam='SEL'
begin
Select code from temp_table;
Goto Fin;
end;
if @ActNam='ADD'
begin
Insert into temp_table (code) Values (@code);
Goto Fin;
end;
FIN:
return(@result);
GO
Ну и вызов в случае добавления - exec s_temp_table @ActNam='ADD', @code=:code выборки - exec s_temp_table @ActNam='SEL'
-
Круто, сейчас у меня глаза на место встанут (они на стол выпали), и я разберусь.. Пока все временное, просто пробую - потом конечно все это обрастет кодом ;)
Спасибо за точный и быстрый ответ
-
А еще такой вопросик, не стал новую тему создавать... Слышал, что в новых версиях msSQL не будет типа данных image. На сколько эти слуи - правда?
-
> Viod (14.07.2008 6:17:08) [8]
Тип будет, имени не будет. А зачем слухами пользуешься?
-
Да не то чтобы пользуюсь - услышал и спросил по быстрому. Имени не будет... Так процедуры хранимые переписывать придется при переводе на новую версию сервера?
-
> if @ActNam='SEL' > begin > Select code from temp_table; > Goto Fin; > end;
Хм... а почему goto, а не else?
-
> Имени не будет... Так процедуры хранимые переписывать придется > при переводе на новую версию сервера?
Возможно и придется, имя типа будет другое.
-
> Хм... а почему goto, а не else?
Это лишь шаблон, там этих @AcNam до чёртиков может быть. Короче, привык так... :)
-
А вот такой вопрос: для того чтобы вытащить из базы blob поле в Stream мы используем ADODataSet. По методу Open он как я понимаю должен вернуть набор записей. А если записи не вернулись, тоесть хранимая процедура не вернула набор записей - дебаггер оворит, что все плохо :) Хранимая процедура выглядит так: IF EXISTS(select .......)
BEGIN
SELECT ...........
RETURN 0
END
ELSE RETURN -1 Так вот когда RETURN -1, тогда Open сделать не выходит... Как обработать этот случай. Или как получить blob с помощью AdoCommand. Пробовал AdoCommand.Execute.Fields[номер поля].value вроде возвращает обычные типы данных а вот blob не хочет
-
> Хранимая процедура выглядит так:
А не надо так делать. Возвращай Select в любом случае. т.е. вместо
IF EXISTS(select .......)
BEGIN
SELECT ...........
RETURN 0
END
ELSE RETURN -1 делай
SELECT .....
RETURN 0
А вот на клиенте уже проверяй: with DataSet do
begin
try
Open;
if IsEmpty then .... else ....
except
....
end;
end;
-
Ясно... Ну а чисто теоретически с AdoCommand реально?
-
> Ну а чисто теоретически с AdoCommand реально?
Реально. _RecordSet же есть. Но не советую. В смысле, как у тебя запрос был сформирован. В одном случае НД возвращается, а в другом - нет. Причём заранее определить нельзя - вернётся он или нет. Это потенциальная дыра.
-
так вот интересно. rec:_recordset;
rec:=AdoCommand.execute; Это вобще правильно или нет?
-
реально но большого смысла нет. AdoCommand как результат возвращает рекордсет т.что можно выполнить в нем и вытаскивать блоб из результирующего рекордсета если он не пустой (рекордсет возвращается в любом случае, просто по пустому в твоем случае уже ADODataSet генерит исключение, а до этого ты сам в процедуре делишь по проверке на пустой и нет... сплошные проверки в общем)
имхо, то что ты делаешь и в процедуру то "заворачивать" смысла нет... (как и 90% написанных sql процедур, их пишут не потому что они действительно нужны, а потому что начинающему сказали что это "круто"/правильно/лучше/удобнее(?)/...)
|