Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
1-1208160423
incm
2008-04-14 12:07
2009.03.29
Как в TreeView убрать у итемсов пустое место для картинки


2-1233895829
des
2009-02-06 07:50
2009.03.29
Как отловить ошибку 405?


15-1232375977
SP
2009-01-19 17:39
2009.03.29
Съемный диск


15-1232623498
дед Маздай
2009-01-22 14:24
2009.03.29
Подскажите способ реализации


15-1233202441
Дмитрий С
2009-01-29 07:14
2009.03.29
Как определить легальность windows xp,...





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский