![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Stream and AdoCommand [D7, MSSQL]
Viod © (2008-07-11 11:40:00)Здравствуйте!
Есть такая задача: нужно сохранить 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);
Параметру не передается значение из потока.
такой вариант записи в базу вобще возможен?
sniknik (2008-07-29 13:32:00) [1]> удаляет запись и возвращает 0. Если записи нет, то возвращает -1.
способ 3... правильный. (бредите вы этими процедурами чтоли?)
- простейший запрос в ADOCommand1, внесенный в десигне, вида
delete from ... where ID=:ID
выполнение
var
RecAff: integer;
begin
ADOCommand1.Parameters.ParamByName('ID').Value:= ...;
ADOCommand1.Execute(RecAff);
if RecAff > 0
then //есть запись, а может и не одна (что подразумевает ID?)
else //нет записей
end;
все. и зачем сложности с процедурами? не нужна она тут.
Viod (2008-07-29 12:54:00) [2]Спс.
Ega23 (2008-07-29 10:16:00) [3]Способ 1.
Declare @X int;
Select @X=exec S_MyProc @Id=18;
Select Result=@X;
Способ 2.
CREATE PROCEDURE s_MyProc
@ID int =-1,
@SelOut int = 1,
@Debug int =0
As
Declare @result int;
if Exists (Select ... from ... where id=@ID)
begin
Delete from ... where ID=@ID
Set @Result=0
end
else
Set Result=-1;
if @SelOut=1
Select Result=@result;
return(@result);
GO
Вызов второго варианта.
Если хочешь получить результат, то через TADODataSet.Open:
exec S_MyProc @ID=...
Если не хочешь получить результат, то через TADOCommand.Execute:
exec S_MyProc @ID=..., @SelOut=0
Viod (2008-07-29 10:05:00) [4]Ко вчерашнему спрору о проверке внутри процедуры или в делфи:
Допустим хранимая процедура получает параметром идентификатор записи. Смотрит есть ли эта записьif EXISTS(SELECT... WHERE Idn=@idn)и удаляет запись и возвращает 0. Если записи нет, то возвращает -1.
Как мне в этом случае оставить проверку на стороне приложения? В смысле как это сделать более-менее коротко и красиво?
Anatoly Podgoretsky (2008-07-28 13:01:00) [5]> sniknik (28.07.2008 12:14:36) [36]
На размере ехе скажется как раз один AdoCommand - не в лучшую сторону конечно.
Ega23 (2008-07-28 12:43:00) [6]
> Спасибо за помощь, думаю не последний раз написал ;)
Не за что, удачи!
Viod (2008-07-28 12:41:00) [7]Удалено модератором
Ega23 (2008-07-28 12:36:00) [8]
>
> Как так?
А где Close?
Viod (2008-07-28 12:32:00) [9]Не могу ниче понять. Может туплю...
Вот 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.
Как так?
sniknik (2008-07-28 12:14:00) [10]> однозначный ответ на вопрос
да. но показывать как не буду, ломает делать бессмысленную работу которая к тому же ухудшит программу если вдруг будет использовано.
> что с базой будет работать один единственный компонент AdoCommand.
а смысл? на компонентах экономить не стоит, раз уж чтото используется, то используется, хоть 1 раз встреченное хоть 128, на размере exe не скажется, проверь, добавь несколько пустышек (без запросов внутри, они то добавятся, а код нет. ООП однако.)
Ega23 (2008-07-28 12:12:00) [11]
> Просто изначально планировалось, что с базой будет работать
> один единственный компонент AdoCommand.
Это не самый лучший вариант. Есть такая вещь, как скомпилированные запросы (Prepared:=True); на такие лучше свой экземпляр TADODataSet или TADOCommand держать.
Ega23 (2008-07-28 12:10:00) [12]
> можно вытащить из базы блоб поле и загрузить его в Stream
> используя AdoCommand, но не используя AdoDataSet
Можно. Но не стОит.
Viod (2008-07-28 12:03:00) [13]:) Сижу и не могу... Давай так: однозначный ответ на вопрос "можно вытащить из базы блоб поле и загрузить его в Stream используя AdoCommand, но не используя AdoDataSet"? Да или Нет? :)
Я же говорю, чисто теоретически. Проблема уже решена благодаря Ega23, за что большое спасибо.
Просто изначально планировалось, что с базой будет работать один единственный компонент AdoCommand. Вот я и мучаю себя и остальных, чтобы однозначно понять реально это или нет
sniknik (2008-07-28 11:54:00) [14]> А поскольку мне приходится использовать aDodataSet - получается что я сделал мартышкин труд.
именно им ты сейчас и занимаешься. нужно упрощать то, что делаешь а не усложнять.
-----------------------------
усложнять просто, упрощать сложно! © не помню чей
sniknik (2008-07-28 11:52:00) [15]> На 2 проверки все разносится потому что я не могу использовать AdoCommand для выборки из базы blob поля.
тебе не предлагали использовать AdoCommand для blob, это было предложено уже для проверки, что и RETURN -1 вернет рекордсет.
по твоей "проблеме" нормальное решение предложил Ega23 © (28.07.08 10:18) [15], проверка в одном месте.
> Объясни лучше как получить значение Blob поля из выборки, исползуя AdoCommand.
это будет ненормальноерешение... но раз так хочется, присвой результат execute рекордсету в ADODataSet и работай уже с ним (или посмотри как он это делает, и повтори... если желаешь еще больше мазохистских удовольствий.).
Viod (2008-07-28 11:31:00) [16]sniknik, мы не поняли друг друга. На 2 проверки все разносится потому что я не могу использовать AdoCommand для выборки из базы blob поля. Если бы я это сделал - я бы использовал возвращаемые хранимой процедурой значения. А поскольку мне приходится использовать aDodataSet - получается что я сделал мартышкин труд. Когда я все это планировал - думал использовать только AdoCommand и только проверки внутри хранимой процедуры.
Объясни лучше как получить значение Blob поля из выборки, исползуя AdoCommand. Blob поле будет допустим в fields[0]
sniknik (2008-07-28 11:17:00) [17]> Просто на деле получается исключение.
sniknik © (28.07.08 10:51) [19]
> просто по пустому в твоем случае уже ADODataSet генерит исключение
> AdoCommand.execute
Viod (2008-07-28 11:15:00) [18]Ну тут я не знаю.. Не специалист. Просто на деле получается исключение. Предлагаешь отключить integrated debugging и смотреть IsEmpty как ни в чем не бывало?
sniknik (2008-07-28 11:13:00) [19]> sniknik, а че плохо чтоле? Получил 0 - работай, получил -1 не работай.
то же самое от запроса. никакой выгоды... как минус разнесение логики на 2 места. (возможно именно это и нужно, но это как раз входит в оставшиеся 10% вместе со сложными процедурами. вряд ли твой случай)
sniknik (2008-07-28 11:10:00) [20]> Где тут НД возвращается, если not exists?
AdoCommand.execute:_recordset;
> Ниче не вернет если нот ексистс проверено :)
тебе это просто не показывают... а на самом деле возвращается, без рекордсета оно не может, там кроме данных в структуре еще информационная инфа есть т.что. в любом случае. гарантированно.