Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Problema con procedimiento almacenado y Delphi (https://www.clubdelphi.com/foros/showthread.php?t=85044)

santiago14 17-01-2014 17:45:14

Problema con procedimiento almacenado y Delphi
 
Buenas, tengo la siguiente llamada a procedimiento almacenado en Delphi:
Código Delphi [-]
function recupero_Valor_Entorno_EBD(nombre_Entorno:string):TStream;
var
  //resultado:TBlobField;
  stream:TStream;
begin
  with DataModule1.spValorEntornoEBD do
  begin
    Close;
    Params.Clear;
    StoredProcName:='RECUPERO_VALOR_ENTORNO_EBD ';  //nombre del store procedure
    Params.CreateParam(ftWideString, 'NOMBRE_ENTORNO', ptInput); //creamos el parametro de entrada
    Params.CreateParam(ftBlob, 'VALOR', ptOutput);   //Valor que recibimos
    ParamByName('NOMBRE_ENTORNO').AsString:=nombre_entorno ;  //le asignamos al param. entrada, su valor
    Prepare; //hacemos que se "arme" el objeto SP
    try
      ExecProc;
      stream:=TStringStream.Create(ParamByName('VALOR').AsString);
      //stream:=StringToStream(ParamByName('VALOR').AsBlob);
      unPrepare;
      Result:=stream;
      //stream.Free;
    except
      UnPrepare;
      //stream.Free;
      raise;
    end; //del try
  end;
end;

Como se ve, recupera desde una tabla de Firebird un valor, que es un BLOB.
El problema es que cuando lo quiero ver en un RichEdit me muestra simplemente "(blob)", y no el contenido del blob.

Pongo el procedimiento almacenado que hice:
Código SQL [-]
CREATE PROCEDURE RECUPERO_VALOR_ENTORNO_EBD (
    nombre_entorno varchar(30))
returns (
    valor blob sub_type 0 segment size 100)
as
begin
  /* Recupero el valor entorno según el nombre_entorno solicitado */
  Select CAST(e.valor_ebd AS BLOB) AS valor_ebd
  From entorno_boletin_digital e
  Where e.nombre_ebd = :nombre_entorno
  into :valor;
  suspend;
end;

Ahora, como lo intento poner en un RichEdit:
Código Delphi [-]
rchGobernador.Lines.LoadFromStream(recupero_Valor_Entorno_EBD('GOBERNADOR'));

Muestro la tabla:
Código SQL [-]
CREATE TABLE ENTORNO_BOLETIN_DIGITAL (
    COD_EBD          INTEGER NOT NULL,
    TIPO_EBD         VARCHAR(10),
    NOMBRE_EBD       VARCHAR(200),
    VALOR_EBD        BLOB SUB_TYPE 0 SEGMENT SIZE 100 CHARACTER SET ISO8859_1,
    DESCRIPCION_EBD  VARCHAR(300)

Agradecería que me dijeran que está pasando porque no le veo la razón para que haga eso.

Saludos.

Neftali [Germán.Estévez] 17-01-2014 18:00:49

Creo que el problema puede estar aquí:

Código Delphi [-]
stream:=TStringStream.Create(ParamByName('VALOR').AsString);

Estás recuperando un BLOB como string. No te da error, pero tiene pinta de que no tiene mucha lógica, dato que un BLOB puede tener cosas que no tengan nada que ver con un String.

A ver si este link te sirve.

santiago14 17-01-2014 19:57:55

Trabajando un poco con el enlace que me diste, hice lo siguiente:
Código Delphi [-]
function recupero_Valor_Entorno_EBD(nombre_Entorno:string):TStream; 
var   
//resultado:TBlobField;   
stream:TMemoryStream; 
begin
   with DataModule1.spValorEntornoEBD do
   begin
     Close;
     Params.Clear;
     StoredProcName:='RECUPERO_VALOR_ENTORNO_EBD ';  //nombre del store procedure
     Params.CreateParam(ftWideString, 'NOMBRE_ENTORNO', ptInput); //creamos el parametro de entrada
     Params.CreateParam(ftBlob, 'VALOR', ptOutput);   //Valor que recibimos
     ParamByName('NOMBRE_ENTORNO').AsString:=nombre_entorno ;  //le asignamos al param. entrada, su valor
     Prepare; //hacemos que se "arme" el objeto SP
     try
       ExecProc;
       stream:=TMemoryStream.Create;
    //Aquí hice el reemplazo de líneas de código.
      //stream:=StringToStream(ParamByName('VALOR').AsBlob);
      TBlobField(FieldByName('valor')).SaveToSream(stream);
      unPrepare;
       Result:=stream;
       //stream.Free;
     except
       UnPrepare;
       //stream.Free;
       raise;
     end; //del try
   end;
 end;

Al ejecutar, me sale el siguiente cartel:
"Imposible recuperar datos...
Mensaje: spValorEntornoEBD: Field 'valor' not found"

El error ocurre cuando lee la línea:
Código Delphi [-]
TBlobField(FieldByName('valor')).SaveToSream(stream);

Santiago.

Neftali [Germán.Estévez] 18-01-2014 00:11:00

Código Delphi [-]
...
Select CAST(e.valor_ebd AS BLOB) AS valor_ebd
...

A lo mejor hay que usar valor_ebd

ecfisa 18-01-2014 05:42:31

Hola.

Hasta donde tengo entendido, Firebird no soporta el pasaje de campos tipo BLOB o ARRAY en los procedimientos almacenados.

¿ No te sirve usar un TIBQuery o TIBDataSet ?, por ejemplo:
Código Delphi [-]
procedure GetBlobField(Qry: TIBQuery; RE: TRichEdit; const aID: Integer);
var
  Stream: TStream;
begin
  Qry.Close;
  Qry.SQL.Text := 'SELECT CAMPO_BLOB FROM TABLA WHERE ID = :P_ID';
  Qry.ParamByName('P_ID').AsInteger := aID;
  Qry.Open;
  Stream := TMemoryStream.Create;
  try
    TBlobField(Qry.FieldByName('CAMPO_BLOB')).SaveToStream(Stream);
    Stream.Seek(0, soFromBeginning);
    RE.PlainText:= False;
    RE.Lines.LoadFromStream(Stream);
  finally
    Stream.Free;
  end;
end;

Saludos :)

santiago14 18-01-2014 15:47:59

Cita:

Empezado por ecfisa (Mensaje 471869)
Hola.

Hasta donde tengo entendido, Firebird no soporta el pasaje de campos tipo BLOB o ARRAY en los procedimientos almacenados.

Ahora sí, con esto queda claro.

Por supuesto que me sirve hacerlo con una consulta, de hecho, voy a seguir el ejemplo que enviaste. La verdad es que no sabía que Firebird no soportaba esta funcionalidad, espero que en versiones posteriores lo implementen.

Gracias.


La franja horaria es GMT +2. Ahora son las 03:29:59.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi