Конференция "Базы" » Stream and AdoCommand [D7, MSSQL]
 
  • Viod © (11.07.08 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 © (11.07.08 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 © (11.07.08 13:03) [2]
    Это осилил, спасибо, а как теперь из базы выгрузить в stream?
  • Ega23 © (11.07.08 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 © (11.07.08 13:12) [4]
    спасибо за оперативность :)
    пойду пробовать
  • Viod © (11.07.08 13:25) [5]
    Все работает.
    Теперь пытаюсь сделать вывод с помощью хранимой процедуры

    если просто то:
    CREATE PROCEDURE temp_out
    AS
    select code from temp_table
    GO

    В принципе я вызываю процедуру, она мне возвращает набор, и я его обрабатываю как описано выше... Так будет работать?
  • Ega23 © (11.07.08 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 © (11.07.08 13:42) [7]
    Круто, сейчас у меня глаза на место встанут (они на стол выпали), и я разберусь..
    Пока все временное, просто пробую - потом конечно все это обрастет кодом ;)

    Спасибо за точный и быстрый ответ
  • Viod © (14.07.08 06:17) [8]
    А еще такой вопросик, не стал новую тему создавать...
    Слышал, что в новых версиях msSQL не будет типа данных image. На сколько эти слуи - правда?
  • Anatoly Podgoretsky © (14.07.08 08:35) [9]
    > Viod  (14.07.2008 6:17:08)  [8]

    Тип будет, имени не будет.
    А зачем слухами пользуешься?
  • Viod © (14.07.08 10:01) [10]
    Да не то чтобы пользуюсь - услышал и спросил по быстрому.
    Имени не будет... Так процедуры хранимые переписывать придется при переводе на новую версию сервера?
  • clickmaker © (14.07.08 11:12) [11]
    > if @ActNam='SEL'
    > begin
    > Select code from temp_table;
    > Goto Fin;
    > end;

    Хм... а почему goto, а не else?
  • Anatoly Podgoretsky © (14.07.08 11:50) [12]

    > Имени не будет... Так процедуры хранимые переписывать придется
    > при переводе на новую версию сервера?

    Возможно и придется, имя типа будет другое.
  • Ega23 © (14.07.08 19:43) [13]

    > Хм... а почему goto, а не else?


    Это лишь шаблон, там этих @AcNam до чёртиков может быть.
    Короче, привык так...  :)
  • Viod © (28.07.08 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 © (28.07.08 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 © (28.07.08 10:42) [16]
    Ясно... Ну а чисто теоретически с AdoCommand реально?
  • Ega23 © (28.07.08 10:47) [17]

    > Ну а чисто теоретически с AdoCommand реально?


    Реально. _RecordSet же есть.
    Но не советую. В смысле, как у тебя запрос был сформирован. В одном случае НД возвращается, а в другом - нет. Причём заранее определить нельзя - вернётся он или нет.
    Это потенциальная дыра.
  • Viod © (28.07.08 10:50) [18]
    так вот интересно.
    rec:_recordset;

    rec:=AdoCommand.execute;
    Это вобще правильно или нет?
  • sniknik © (28.07.08 10:51) [19]
    реально но большого смысла нет.
    AdoCommand как результат возвращает рекордсет т.что можно выполнить в нем и вытаскивать блоб из результирующего рекордсета если он не пустой (рекордсет возвращается в любом случае, просто по пустому в твоем случае уже ADODataSet генерит исключение, а до этого ты сам в процедуре делишь по проверке на пустой и нет... сплошные проверки в общем)

    имхо, то что ты делаешь и в процедуру то "заворачивать" смысла нет... (как и 90% написанных sql процедур, их пишут не потому что они действительно нужны, а потому что начинающему сказали что это "круто"/правильно/лучше/удобнее(?)/...)
 
Конференция "Базы" » Stream and AdoCommand [D7, MSSQL]
Есть новые Нет новых   [134473   +28][b:0][p:0.002]