Форум: "Базы";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
ВнизStream and AdoCommand Найти похожие ветки
← →
Viod © (2008-07-11 11:40) [0]Здравствуйте!
Есть такая задача: нужно сохранить 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);
Параметру не передается значение из потока.
такой вариант записи в базу вобще возможен?
← →
Ega23 © (2008-07-11 11:53) [1]
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;
← →
Viod © (2008-07-11 13:03) [2]Это осилил, спасибо, а как теперь из базы выгрузить в stream?
← →
Ega23 © (2008-07-11 13:09) [3]
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;
← →
Viod © (2008-07-11 13:12) [4]спасибо за оперативность :)
пойду пробовать
← →
Viod © (2008-07-11 13:25) [5]Все работает.
Теперь пытаюсь сделать вывод с помощью хранимой процедуры
если просто то:
CREATE PROCEDURE temp_out
AS
select code from temp_table
GO
В принципе я вызываю процедуру, она мне возвращает набор, и я его обрабатываю как описано выше... Так будет работать?
← →
Ega23 © (2008-07-11 13:32) [6]
> Так будет работать?
>
Да.
Только я бы сделал такую процедуру: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"
← →
Viod © (2008-07-11 13:42) [7]Круто, сейчас у меня глаза на место встанут (они на стол выпали), и я разберусь..
Пока все временное, просто пробую - потом конечно все это обрастет кодом ;)
Спасибо за точный и быстрый ответ
← →
Viod © (2008-07-14 06:17) [8]А еще такой вопросик, не стал новую тему создавать...
Слышал, что в новых версиях msSQL не будет типа данных image. На сколько эти слуи - правда?
← →
Anatoly Podgoretsky © (2008-07-14 08:35) [9]> Viod (14.07.2008 6:17:08) [8]
Тип будет, имени не будет.
А зачем слухами пользуешься?
← →
Viod © (2008-07-14 10:01) [10]Да не то чтобы пользуюсь - услышал и спросил по быстрому.
Имени не будет... Так процедуры хранимые переписывать придется при переводе на новую версию сервера?
← →
clickmaker © (2008-07-14 11:12) [11]> if @ActNam="SEL"
> begin
> Select code from temp_table;
> Goto Fin;
> end;
Хм... а почему goto, а не else?
← →
Anatoly Podgoretsky © (2008-07-14 11:50) [12]
> Имени не будет... Так процедуры хранимые переписывать придется
> при переводе на новую версию сервера?
Возможно и придется, имя типа будет другое.
← →
Ega23 © (2008-07-14 19:43) [13]
> Хм... а почему goto, а не else?
Это лишь шаблон, там этих @AcNam до чёртиков может быть.
Короче, привык так... :)
← →
Viod © (2008-07-28 10:09) [14]А вот такой вопрос: для того чтобы вытащить из базы 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 не хочет
← →
Ega23 © (2008-07-28 10:18) [15]
> Хранимая процедура выглядит так:
А не надо так делать. Возвращай 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;
← →
Viod © (2008-07-28 10:42) [16]Ясно... Ну а чисто теоретически с AdoCommand реально?
← →
Ega23 © (2008-07-28 10:47) [17]
> Ну а чисто теоретически с AdoCommand реально?
Реально. _RecordSet же есть.
Но не советую. В смысле, как у тебя запрос был сформирован. В одном случае НД возвращается, а в другом - нет. Причём заранее определить нельзя - вернётся он или нет.
Это потенциальная дыра.
← →
Viod © (2008-07-28 10:50) [18]так вот интересно.
rec:_recordset;
rec:=AdoCommand.execute;
Это вобще правильно или нет?
← →
sniknik © (2008-07-28 10:51) [19]реально но большого смысла нет.
AdoCommand как результат возвращает рекордсет т.что можно выполнить в нем и вытаскивать блоб из результирующего рекордсета если он не пустой (рекордсет возвращается в любом случае, просто по пустому в твоем случае уже ADODataSet генерит исключение, а до этого ты сам в процедуре делишь по проверке на пустой и нет... сплошные проверки в общем)
имхо, то что ты делаешь и в процедуру то "заворачивать" смысла нет... (как и 90% написанных sql процедур, их пишут не потому что они действительно нужны, а потому что начинающему сказали что это "круто"/правильно/лучше/удобнее(?)/...)
← →
sniknik © (2008-07-28 10:53) [20]> В одном случае НД возвращается, а в другом - нет.
в любом случае возвращается.
← →
Viod © (2008-07-28 11:00) [21]просто хочется всю безопасность со своего кода на sql переложить
← →
Ega23 © (2008-07-28 11:01) [22]
> в любом случае возвращается.
IF EXISTS(select .......)
BEGIN
SELECT ...........
RETURN 0
END
ELSE RETURN -1
Где тут НД возвращается, если not exists?
← →
Viod © (2008-07-28 11:03) [23]Ниче не вернет если нот ексистс проверено :)
← →
Viod © (2008-07-28 11:08) [24]sniknik, а че плохо чтоле? Получил 0 - работай, получил -1 не работай.
А если тебе нужно по сложному алгоритму что-то из базы получать. Клиентская машина итак еле шевелится. Перекладываешь все на SQL"ник и все. Код в дельфи прилично выглядит: не приходится запросы писать, а они ведь бывают очень длинными. Да и потом хранимые процедуры и с представлениями могут работать.. Попробуй ка все в делфи впихнуть :)
А проверки в хранимых процедурах... пустой набор записей когда возвращается - тоже вроде не очень приятно?
← →
Viod © (2008-07-28 11:08) [25]sniknik, а че плохо чтоле? Получил 0 - работай, получил -1 не работай.
А если тебе нужно по сложному алгоритму что-то из базы получать. Клиентская машина итак еле шевелится. Перекладываешь все на SQL"ник и все. Код в дельфи прилично выглядит: не приходится запросы писать, а они ведь бывают очень длинными. Да и потом хранимые процедуры и с представлениями могут работать.. Попробуй ка все в делфи впихнуть :)
А проверки в хранимых процедурах... пустой набор записей когда возвращается - тоже вроде не очень приятно?
← →
sniknik © (2008-07-28 11:10) [26]> Где тут НД возвращается, если not exists?
AdoCommand.execute:_recordset;
> Ниче не вернет если нот ексистс проверено :)
тебе это просто не показывают... а на самом деле возвращается, без рекордсета оно не может, там кроме данных в структуре еще информационная инфа есть т.что. в любом случае. гарантированно.
← →
sniknik © (2008-07-28 11:13) [27]> sniknik, а че плохо чтоле? Получил 0 - работай, получил -1 не работай.
то же самое от запроса. никакой выгоды... как минус разнесение логики на 2 места. (возможно именно это и нужно, но это как раз входит в оставшиеся 10% вместе со сложными процедурами. вряд ли твой случай)
← →
Viod © (2008-07-28 11:15) [28]Ну тут я не знаю.. Не специалист. Просто на деле получается исключение. Предлагаешь отключить integrated debugging и смотреть IsEmpty как ни в чем не бывало?
← →
sniknik © (2008-07-28 11:17) [29]> Просто на деле получается исключение.
sniknik © (28.07.08 10:51) [19]
> просто по пустому в твоем случае уже ADODataSet генерит исключение
> AdoCommand.execute
← →
Viod © (2008-07-28 11:31) [30]sniknik, мы не поняли друг друга. На 2 проверки все разносится потому что я не могу использовать AdoCommand для выборки из базы blob поля. Если бы я это сделал - я бы использовал возвращаемые хранимой процедурой значения. А поскольку мне приходится использовать aDodataSet - получается что я сделал мартышкин труд. Когда я все это планировал - думал использовать только AdoCommand и только проверки внутри хранимой процедуры.
Объясни лучше как получить значение Blob поля из выборки, исползуя AdoCommand. Blob поле будет допустим в fields[0]
← →
sniknik © (2008-07-28 11:52) [31]> На 2 проверки все разносится потому что я не могу использовать AdoCommand для выборки из базы blob поля.
тебе не предлагали использовать AdoCommand для blob, это было предложено уже для проверки, что и RETURN -1 вернет рекордсет.
по твоей "проблеме" нормальное решение предложил Ega23 © (28.07.08 10:18) [15], проверка в одном месте.
> Объясни лучше как получить значение Blob поля из выборки, исползуя AdoCommand.
это будет ненормальное решение... но раз так хочется, присвой результат execute рекордсету в ADODataSet и работай уже с ним (или посмотри как он это делает, и повтори... если желаешь еще больше мазохистских удовольствий.).
← →
sniknik © (2008-07-28 11:54) [32]> А поскольку мне приходится использовать aDodataSet - получается что я сделал мартышкин труд.
именно им ты сейчас и занимаешься. нужно упрощать то, что делаешь а не усложнять.
-----------------------------
усложнять просто, упрощать сложно! © не помню чей
← →
Viod © (2008-07-28 12:03) [33]:) Сижу и не могу... Давай так: однозначный ответ на вопрос "можно вытащить из базы блоб поле и загрузить его в Stream используя AdoCommand, но не используя AdoDataSet"? Да или Нет? :)
Я же говорю, чисто теоретически. Проблема уже решена благодаря Ega23, за что большое спасибо.
Просто изначально планировалось, что с базой будет работать один единственный компонент AdoCommand. Вот я и мучаю себя и остальных, чтобы однозначно понять реально это или нет
← →
Ega23 © (2008-07-28 12:10) [34]
> можно вытащить из базы блоб поле и загрузить его в Stream
> используя AdoCommand, но не используя AdoDataSet
Можно. Но не стОит.
← →
Ega23 © (2008-07-28 12:12) [35]
> Просто изначально планировалось, что с базой будет работать
> один единственный компонент AdoCommand.
Это не самый лучший вариант. Есть такая вещь, как скомпилированные запросы (Prepared:=True); на такие лучше свой экземпляр TADODataSet или TADOCommand держать.
← →
sniknik © (2008-07-28 12:14) [36]> однозначный ответ на вопрос
да. но показывать как не буду, ломает делать бессмысленную работу которая к тому же ухудшит программу если вдруг будет использовано.
> что с базой будет работать один единственный компонент AdoCommand.
а смысл? на компонентах экономить не стоит, раз уж чтото используется, то используется, хоть 1 раз встреченное хоть 128, на размере exe не скажется, проверь, добавь несколько пустышек (без запросов внутри, они то добавятся, а код нет. ООП однако.)
← →
Viod © (2008-07-28 12:32) [37]Не могу ниче понять. Может туплю...
Вот t-sql:
CREATE PROCEDURE s_select_vopros_by_id
@id_vopros int=0
AS
SELECT * FROM new_test.dbo.t_vopros WHERE id_vopros=@id_vopros
Вот Delphi:
with data.ADODataSet1 do begin
CommandText:="exec s_select_vopros_by_id @id_vopros=:id_vopros";
Parameters.ParamByName("id_vopros").Direction:=pdInput;
Parameters.ParamByName("id_vopros").Value:=number;
Open;
If not(IsEmpty) then
Showmessage(FieldByName("id_vopros").value);
end;
Первый раз код делфи проходит с number: = 110 - все норм, второй раз с number:=112 - showmessage ВОЗВРАЩАЕТ 110.
Как так?
← →
Ega23 © (2008-07-28 12:36) [38]
>
> Как так?
А где Close?
← →
Viod © (2008-07-28 12:41) [39]Удалено модератором
← →
Ega23 © (2008-07-28 12:43) [40]
> Спасибо за помощь, думаю не последний раз написал ;)
Не за что, удачи!
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.038 c