PDA

Ver la Versión Completa : insertar un archivo en un campo blob desde delphi


thelibmx
13-12-2007, 03:01:06
hola amigos yo se que muchos tal ves se molesten y digan que busque en los hilos pero en verdad que estuve buscando y no encontre mucho que me pueda ayudar o mas bien, me falta un poco de conocimiento, asi que recurro a ustedes, lo que quiero hacer es subir un archivo a una base de datos que es postgre(<-no se espanten no es cosa del otro mundo) digamos que en vez de postgre dije mysql el procedimiento es similar(muchos temen al coco postgre), tengo delphi2006, tengo un tdatabase y un tquery se insertar informacion a la base de datos, lo que no me queda claro es como insertar el archivo en el campo tipo blob, cuando digo el archivo puede ser de diferentes tipos, pdf,doc,ppt,xls, etc.

En teoria cuando doy click en el boton ,se abre el opendialog y selecciono el archivo que se pretende subir a la base de datos, la base de datos se llama "basedatosprueba" y la tabla adonde van los archivos se llama "tabla_prueba", esta tiene tres campos que son, llave(integer),nombre(character) y archivoblob(blob)

este es parte del codigo que utilizo, lo que no se es como insertar el archivo dentro del campo, puedo insertar en los demas campos informacion pero el archivo en el blob no, seria de mucha ayuda si alguien me explicara un poco como es que se hace,



procedure TFrmenuu.BitBtn1Click(Sender: TObject);
var
blob:TStream;
fs:tstream;
begin
if OpenDialog.Execute then
begin
Olecontainer1.CreateObjectFromFile(PChar(OpenDialog.FileName),false);
vertbar.max:= Olecontainer1.Height;
horzbar.max:= Olecontainer1.Height;
Panelcontenedor.Visible:=true;
Querygestion.Close;
Querygestion.SQL.Clear;
Querygestion.SQL.Add('insert into tabla_prueba(llave,nombre,archivoblob) values(006,'1',blob)');
Querygestion.ExecSQL;
Querygestion.Open;
showmessage('agregado');
blob := Querygestion.CreateBlobStream(Querygestion.FieldByName('archivoblob'),bmWrite);
try
blob.Seek(0, soFromBeginning);
fs := TFileStream.Create(OpenDialog.FileName, fmOpenRead or fmShareDenyWrite);
try
blob.CopyFrom(fs, fs.Size)
finally
fs.Free
end;
finally
blob.Free
end;

end;
end;



Les agradezco su atencion y su ayuda, cualquier duda o sugerencia es bienvenida :confused:

Caral
13-12-2007, 03:15:41
Hola
Ya sabes, no me hagas mucho caso por que no entiendo muy bien tu codigo, pero lo que veo es esto.

procedure TFrmenuu.BitBtn1Click(Sender: TObject);
var
blob:TStream;
fs:tstream;
begin
if OpenDialog.Execute then
begin
Olecontainer1.CreateObjectFromFile(PChar(OpenDialog.FileName),false);
vertbar.max:= Olecontainer1.Height;
horzbar.max:= Olecontainer1.Height;
Panelcontenedor.Visible:=true;
// esto no se para que es, lo puse arriba para probar
//blob := Querygestion.CreateBlobStream(Querygestion.FieldByName('archivoblob'),bmWrite);

Querygestion.Close;
// Querygestion.SQL.Clear; // no me gusta
Querygestion.SQL.Text:= 'insert into tabla_prueba(llave,nombre,archivoblob) values(006,'1',blob)';
Querygestion.ExecSQL;
// Querygestion.Open; // esto y lo anterior es lo mismo, solo que este enseña el resultado y el otro nada mas lo ejecuta sin enseñarlo
showmessage('agregado');

try
blob.Seek(0, soFromBeginning);
fs := TFileStream.Create(OpenDialog.FileName, fmOpenRead or fmShareDenyWrite);
try
blob.CopyFrom(fs, fs.Size)
finally
fs.Free
end;
finally
blob.Free
end;

end;
end;
Bueno, hasta aqui, si ves algo, lo dices.
Saludos

juanlaplata
13-12-2007, 13:59:22
No te dara problema las comillas simple en '1' de values ?Querygestion.SQL.Text:= 'insert into tabla_prueba (
llave,nombre,archivoblob) values(006,'1',blob)';

thelibmx
13-12-2007, 17:57:10
ok explico un poco mi codigo hasta donde yo entiendo
la parte de arriba es por que el archivo que voy a subir a la base de datos la mando a un olecontainer para que se muestre




procedure TFrmenuu.BitBtn1Click(Sender: TObject);
var
blob:TStream;
fs:tstream;
begin

if OpenDialog.Execute then // esto es para abrir el opendialog
begin
Olecontainer1.CreateObjectFromFile(PChar(OpenDialog.FileName),false);//aqui le paso el archivo al olecontainer
vertbar.max:= Olecontainer1.Height;//esto es para la barras vertical
horzbar.max:= Olecontainer1.Height;// esto es para la barra horizontal
Panelcontenedor.Visible:=true;// este es un panel donde esta el olecontainer
blob := Querygestion.CreateBlobStream(Querygestion.FieldByName('archivoblob'),bmWrite); //aqui supongo por que no se bien pero se inicializa el tipo blob
Querygestion.Close;// con este cierro el query
// Querygestion.SQL.Clear; // este es para limpiar el query de alguna otra busqueda
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''',blob)');//con este inserto
Querygestion.ExecSQL;// con este executo
// Querygestion.Open; // esto y lo anterior es lo mismo, solo que este enseña el resultado y el otro nada mas lo ejecuta sin enseñarlo
showmessage('agregado');
try // de aqui para abajo ya no se nada no se por que estan las lineas me doy una idea pero no se muy bien
blob.Seek(0, soFromBeginning);
fs := TFileStream.Create(OpenDialog.FileName, fmOpenRead or fmShareDenyWrite);
try
blob.CopyFrom(fs, fs.Size)
finally
fs.Free
end;
finally
blob.Free
end;
end;
end;



este codigo tal cual lo puse y me manda un error de EDatabaseerrror 'querygestion:field'archivoblob' not found, supongo que no encuentra ese campo aunque si existe en la base de datos, sigo revisando si pueden ayudarme o sugerir algo es bienvenido gracias por su atencion

thelibmx
13-12-2007, 20:57:38
Hola
Ya sabes, no me hagas mucho caso por que no entiendo muy bien tu codigo, pero lo que veo es esto.



si mira en pocas palabras lo que hago es que cuando yo aprieto un boton, se abre un opendialog, en el escojo un archivo, y ese archivo cualquiera que sea lo asigno a un olecontainer para visualizarlo, puede ser excel, word, pdf,powert point, etc. entonces yo quiero que ese archivo se suba a una base de datos que tengo, con otros datos que tengo en unos cuadros de texto, yo agrego datos a la base de datos atraves de un query, lo que no se es como agregar el archivo a la base de datos, el codigo que utilizo para eso es asi
Querygestion.Close;
Querygestion.SQL.Clear;
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre) values('+Edit1.Text+','''+tdEditAsunto.Text+''')');
Querygestion.ExecSQL;
showmessage('agregado');

con eso inserto los datos, pero el archivo que seleccione lo quiero insertar en la misma tabla en un campo que se llama 'archivobob', pero eso es lo que no se, quisiera si se pudiera, hacer algo mas o menos asi para poder insertar el archivo tambien

Querygestion.Close;
Querygestion.SQL.Clear;
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''','+archivoquequierosubir+')');
Querygestion.ExecSQL;
showmessage('agregado');



se me complica lo de subir el archivo, los codigos que hay en los foros, he intentado probarlos y pues no los comprendo bien, pues no obtengo resultados :confused: les agradeceria mucho si me pudieran ayudar

Caral
13-12-2007, 21:15:11
Hola
Yo de estas cosas no se, pero si el nombre blob es una variable de tipo tstream (blob:TStream; ), no se tendria que concatenar tambien?


Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''','+blob+')');
No se, la verdad es solo un pensamiento.:)
Saludos

thelibmx
13-12-2007, 21:32:20
Hola
Yo de estas cosas no se, pero si el nombre blob es una variable de tipo tstream (blob:TStream; ), no se tendria que concatenar tambien?


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''','+blob+')');




si pero marca error de tipo de datos
[Pascal Error] frmenu.pas(198): E2010 Incompatible types: 'string' and 'TStream'
alguna sugerencia?

Caral
13-12-2007, 21:49:25
Hola
Pues parece que el campo blob es string, recuerda, no se de esto.:)
Tal vez asi:

Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''','+QuotedStr(blob)+')');
Saludos

thelibmx
13-12-2007, 21:59:49
agradesco tu ayuda en verdad, yo estoy mas perdido, pero algo bueno siempre se aprende, se supone que blob esta declarado como Tstream, aun con el QuotedStr sigue marcando el mismo error, creo que hay algo que se esta pasando o tal ves es la manera incorrecta de hacerlo


procedure TFrmenuu.BitBtn1Click(Sender: TObject);
var
blob:TStream;
blobf:TBlobField;
fs:tstream;
begin
if OpenDialog.Execute then
begin
Olecontainer1.CreateObjectFromFile(PChar(OpenDialog.FileName),false);
vertbar.max:= Olecontainer1.Height;
horzbar.max:= Olecontainer1.Height;
Panelcontenedor.Visible:=true;
Querygestion.Close;
Querygestion.SQL.Clear;
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values('+Edit1.Text+','''+tdEditAsunto.Text+''','+QuotedStr(blob)+')');
Querygestion.ExecSQL;
//Querygestion.Open;
showmessage('agregado');

blob:=querygestion.CreateBlobStream(querygestion.DataSource.DataSet.FieldByName('archivoblob'), bmwrite);
//
try
blob.Seek(0, soFromBeginning);
with TFileStream.Create(OpenDialog.FileName, fmCreate) do
try
CopyFrom(blob, blob.Size)
finally
Free
end;
finally
blob.Free
end;
end;
end;



no pense que fuera tan complicado subir un archivo a una base de datos :confused:

Caral
13-12-2007, 22:04:22
lo he tratado de arreglar pero no se ve bien
Si algun moderador lo arregla, por favor
Esta en el siguiente post.
Gracias

Caral
13-12-2007, 22:10:18
Hola
Y asi:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)var blob:TBlobStream;
blobf:TBlobField;
fs:tstream;
begin

Este es el ejemplo completo

Código Delphi [-] (http://www.clubdelphi.com/foros/#)procedure TForm1.Button1Click(Sender: TObject);
var
Stream1: TBlobStream;
Stream2: TStream;
begin
Stream1 := TBlobStream.Create(Table1Notes, bmRead);
try ClientDataSet1.Edit; { here’s a different way to create a blob stream }
Stream2 := ClientDataSet1.CreateBlobStream(ClientDataSet1.FieldByName('Remarks'), bmReadWrite);
try
Stream2.CopyFrom(Stream1, Stream1.Size); ClientDataSet1.Post;
finally
Stream2.Free;
end;

finally Stream1.Free;
end;
end;



Insisto, no se, pero esta en el help
Saludos

Caral
13-12-2007, 22:20:08
Hola
Ya consulte a mi Maestro Egostar y en el help sale esto:

procedure TForm1.Button1Click(Sender: TObject);

var
Stream1, Stream2 : TIBBlobStream;
begin
Stream1 := TIBBlobStream.Create(IBTable1Notes);
try
Stream1.Mode = bmRead;
IBTable2.Edit;
{ here’s a different way to create a blob stream }
{ note that with this one, we don’t need a try.. finally clause }
{ because we are not responsible for freeing the stream }
Stream2 := IBTable2.CreateBlobStream(IBTable2.FieldByName('Remarks'), bmReadWrite);
Stream2.CopyFrom(Stream1, Stream1.Size);

IBTable2.Post;
finally
Stream1.Free;
end;
end;
Ahi lo dice todo.
Saludos

thelibmx
13-12-2007, 23:23:47
no se si sea mucho abusar pero podrias explicar un poco el codigo ?:confused:

Delfino
14-12-2007, 01:20:30
La cosa es mas sencilla q esto :
un campo Blob persistente tiene los metodos LoadFromFile y LoadFromStream, o bien haces un cast a la clase TBlobField, si el campo no es persistente,

CampoBlob.LoadFromFile(..);
(Dataset.FieldByName('NombreBlob') as TBlobField).LoadFromSream(..);

te quedas con el q mas te conviene de los dos..

thelibmx
14-12-2007, 01:32:59
La cosa es mas sencilla q esto :
un campo Blob persistente tiene los metodos LoadFromFile y LoadFromStream, o bien haces un cast a la clase TBlobField, si el campo no es persistente,

Código Delphi [-] (http://www.clubdelphi.com/foros/#)
CampoBlob.LoadFromFile(..);
(Dataset.FieldByName('NombreBlob') as TBlobField).LoadFromSream(..);




te quedas con el q mas te conviene de los dos..

ok, gracias delfino, mira me da pena decir esto pero soy super nuevo en eso de los campos blob, mas o menos intento entender como es que se lleva ese proceso pero no me queda claro, cuando pones campoblob.loadfromstream campoblob se refiere al nombre del campo donde se va insertar el archivo ¿? o a que, yo ocupo un tquery para insertar los datos, me es util ese query o tengo que agregar algun componente¿? eso es lo que no me queda claro, o donde debo agregar la linea para que suba el archivo a la hora de hacer el insert, mi codigo es el que esta arriba, no se si puedas apoyarme un poco o darme una pista, de antemano gracias por tu ayuda :confused:

sitrico
14-12-2007, 03:06:09
Bueno mira no se si ayude o complique la cosa a estas alturas pero te recomiendo lo siguiente:

Modifica la sentencia SQL asi:

Original:
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values '+
Edit1.Text+','''+tdEditAsunto.Text+''','+QuotedStr(blob)+')');


Modificada:
Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values '+
'(:llave,:nombre,:archivoblob)');


De esa manera usarás parametros para manipular los datos en SQL (el nombre del campo precedido de dos puntos ":")

Luego (creo) que puedes hacer:


Querygestion.ParamByName('llave').asinteger := unentero;
Querygestion.ParamByName('nombre').AsString := uncharacter
Querygestion.ParamByName('archivoblob').AsString := memo.text

Tambien tengo por ahi un codigo para el loadfromfile y loadfromstream pero no en este equipo prueba y si te sirve mañana te puedo poner más información.

thelibmx
14-12-2007, 07:36:58
muchas gracias sitrico, pues ahorita no puedo probar el codigo por que estoy en mi casa pero llegando al trabajo lo pruebo y te digo que tal, veo que el archivoblob, esta asignado a un memotext, supongo que eso es para subir un archivo de texto, me parece que si quisiera hacerlo con cualquier tipo de archivo tendria que ser un loadstream, ojala puedas postear el otro codigo, de antemano muchas gracias por la atencion y pues por la ayuda :)

sitrico
15-12-2007, 01:50:26
No pude enviarlo hoy pero encntré este ejemplo:

procedure TForm1.loadPic;
var
jpeg: TJPEGImage;
Stream: TMemoryStream;
BlobField: TBlobField;
begin
BlobField := table1.DataSet.FieldByName('Bild') as TBlobField;
jpeg := TJPEGImage.Create;
try
if (Image1.Picture.Graphic is TJPegImage) then begin
jpeg.Assign (ImageFoto.Picture.Bitmap);
end;
Stream := TMemoryStream.Create;
try
jpeg.SaveToStream (Stream);
DataSourceForm.DataSet.Edit;
BlobField.LoadFromStream (Stream);
finally
Stream.Free;
end;
finally
jpeg.Free;
end;
end;


El TBlobField es más o menos equivalente al Querygestion.ParamByName(BlobField).

thelibmx
17-12-2007, 18:16:45
[quote=sitrico;252575]Bueno mira no se si ayude o complique la cosa a estas alturas pero te recomiendo lo siguiente:

Modifica la sentencia SQL asi:

Original:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values '+
Edit1.Text+','''+tdEditAsunto.Text+''','+QuotedStr(blob)+')');





Modificada:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)Querygestion.SQL.add('insert into tabla_prueba(llave,nombre,archivoblob) values '+
'(:llave,:nombre,:archivoblob)');





De esa manera usarás parametros para manipular los datos en SQL (el nombre del campo precedido de dos puntos ":")

Luego (creo) que puedes hacer:


Código Delphi [-] (http://www.clubdelphi.com/foros/#)
Querygestion.ParamByName('llave').asinteger := unentero;
Querygestion.ParamByName('nombre').AsString := uncharacter
Querygestion.ParamByName('archivoblob').AsString := memo.text




quote]
con ese codigo manda un mensaje de "table is read only" ya verifique en las propiedades del ttable y la propiedad read only esta desactivada, cheque en el tdatabase haber si podria haber alguna propiedad ahi y no encontre algo que pudiera afectar, alguna sugerencia o comentario que me pudieran dar?
:confused:

gracias

Chris
17-12-2007, 19:22:53
con ese codigo manda un mensaje de "table is read only" ya verifique en las propiedades del ttable y la propiedad read only esta desactivada, cheque en el tdatabase haber si podria haber alguna propiedad ahi y no encontre algo que pudiera afectar, alguna sugerencia o comentario que me pudieran dar?
:confused:

gracias

Creo que necesitarás un TUpdateSQL si es que estás utilizando un componente TQuery.

Saludos.

thelibmx
17-12-2007, 20:28:27
en efecto si estoy utilizando un tquery.

El TUpdateSQL es un componente que no he ocupado aun, lo uso en sustitucion del tquery? o como lo pongo en marcha? eh buscado un poco en los foros y creo que lo tendria qe ligar al t query pero no se muy bien, sigo buscando sobre tupdatesql, si pones un poco de codigo me serviria de ayuda a entender mejor agradezco tu ayuda D&W, vaya que estoy sufriendo con subir archivos a la base de datos :rolleyes:

Chris
17-12-2007, 21:24:12
primero, el TUpdateSQL tiene es un componente que normalmente, se encuentra dentro de la misma paleta que el TQuery. El TQuery tiene una propiedad lladada UpdateObject, en esta es donde relacionas el TQuery con el TUpdateSQL.

Ahora, tendrás que ingresar secuencias SQL en el TUpdateSQL, para esto haz doble-clic en modo de diseño sobre el componente TUpdateSQL, donde se te mostrará una ventana en donde las podrás ingresar. Trae opciones para que el sistema te las genere automáticamente. Puedes buscar más ayuda al respecto en la ayuda de Delphi o aca en los foros.

Saludos.

thelibmx
21-12-2007, 21:45:18
ya agregue el tupdatesql, modifique un poco el codigo puse entonces mi codigo es asi

procedure TFrmenuu.BitBtn1Click(Sender: TObject);
begin
if OpenDialog.Execute then
begin
Olecontainer1.CreateObjectFromFile(PChar(OpenDialog.FileName),false);
vertbar.max:= Olecontainer1.Height;
horzbar.max:= Olecontainer1.Height;
Panelcontenedor.Visible:=true;
showmessage(OpenDialog.FileName);
Querygestion.Active:=true;
Querygestion.Insert;
QuerygestionLlave.Value :=strtoint(Edit1.Text);
QuerygestionNOMBRE.Value :=tdEditAsunto.Text;
QuerygestionARCHIVOBLOB.loadFromFile(OpenDialog.FileName);
Querygestion.Post;
showmessage('agregado');
//fin del boton de carga de documento
end;
end;



sorry por usar esas etiquetas pero no habia etiquetas de delphi
ese codigo genera este error:
general sql error. Error while executing the query; ERROR: no existe el tipo <<lo>>.
si alguien tiene una pista se los agradecere