Power Builder - Problema con selectblob

 
Vista:

Problema con selectblob

Publicado por Marcelo (2 intervenciones) el 24/09/2009 23:24:02
Saludos, tengo problemas al realizar una consulta para desplegar una imagen de la base de datos.
La cuestión es sencilla, no se despliega, he probado varios scripts de varios foros y no funciona, utilizo pb10.5 con sybase 15, será tal vez el tipo de dato del campo donde los guardo, es un image; debería guardarlos en un campo con otro tipo. Agradezco de anetmano.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil

RE:Problema con selectblob

Publicado por francisco portales (214 intervenciones) el 25/09/2009 18:47:46
/* Yo uso esto con sql 2000 y pb 10.5
utilizo un campo imagen...algo similar con access, tipo ole
con oracle tipo blob con sql anywhare y con todos me ha funcionado.
yo muestro con esto foto, firma y huellas izquierza y derecha.

saludos
*/
string ls_title
int li_rc, li_setpict,li_tipo
long xcod_afiliado, xnumero_firma, row,LL_CUANTOS,ll_cuantos_firmas,ll_cuantos_derecha,ll_cuantos_izquierda
BLOB LB_FOTO,LB_NULL,lb_huella_izq,lb_huella_der

setnull(ibl_blob)
setnull(ibl_firma)
setnull(ibl_huella_izq)
setnull(ibl_huella_der)


p_1.SetPicture(ibl_blob)
p_2.SetPicture(ibl_firma)
p_izq.SetPicture(IBL_huella_izq)
p_der.SetPicture(IBL_huella_der)

row = THIS.GetRow()

int max

if this.rowcount()>0 then


li_tipo=INT(this.object.tipo[currentrow])
ii_tipo=INT(this.object.tipo[currentrow])
xcod_afiliado = long(this.object.idl[currentrow])

xnumero_firma =1//this.object.numero_firma[currentrow]

// FOTO
SELECT isnull(COUNT(*),0) INTO :LL_CUANTOS
FROM DBO.FOTO
WHERE foto is not null
and idl=:xcod_afiliado
AND tipo=:li_tipo;

// FIRMA
SELECT isnull(COUNT(*),0) INTO :ll_cuantos_firmas
FROM DBO.FOTO
WHERE firma is not null
and idl=:xcod_afiliado
AND tipo=:li_tipo;


// HUELLA DERECHA
SELECT isnull(COUNT(*),0) INTO :ll_cuantos_derecha
FROM DBO.FOTO
WHERE huella_der is not null
and idl=:xcod_afiliado
AND tipo=:li_tipo;

// HUELLA IZQUIERDA
SELECT isnull(COUNT(*),0) INTO :ll_cuantos_izquierda
FROM DBO.FOTO
WHERE huella_izq is not null
and idl=:xcod_afiliado
AND tipo=:li_tipo;

//CARA
if LL_CUANTOS>0 then
SELECTblob FOTO INTO :ibl_blob
FROM DBO.FOTO
WHERE FOTO is not null AND
idl=:xcod_afiliado
AND tipo=:li_tipo;

if SQLCA.SQLCode <> 0 then
rollback;
else
commit;
end if

end if

// FIRMA

if ll_cuantos_firmas>0 then
SELECTblob FIRMA INTO :ibl_firma
FROM DBO.FOTO
WHERE firma is not null AND
idl=:xcod_afiliado
AND tipo=:li_tipo;

if SQLCA.SQLCode <> 0 then
rollback;
else
commit;
end if

end if



// HUELLAS ---

if ll_cuantos_derecha>0 then
SELECTblob huella_der INTO :lb_huella_der
FROM DBO.FOTO
WHERE HUELLA_DER is not null AND
idl=:xcod_afiliado
AND tipo=:li_tipo;

if SQLCA.SQLCode <> 0 then
rollback;
else
commit;
end if

end if

if ll_cuantos_izquierda>0 then
SELECTblob huella_izq INTO :lb_huella_izq
FROM DBO.FOTO
WHERE HUELLA_IZQ is not null AND
idl=:xcod_afiliado
AND tipo=:li_tipo;

if SQLCA.SQLCode <> 0 then
rollback;
else
commit;
end if

end if





//lb_huella_izq,lb_huella_der

p_1.hide( )
p_2.hide( )
p_izq.hide( )
p_der.hide( )



IF p_1.SetPicture(ibl_blob) <> 1 or isnull(ibl_blob) then
setnull(ibl_blob)
p_1.SetPicture(ibl_blob)
else
p_1.show( )
end if


IF p_2.SetPicture(ibl_firma) <> 1 or isnull(ibl_firma) then
setnull(ibl_firma)
p_2.SetPicture(ibl_firma)
else
p_2.show( )
end if


IF p_der.SetPicture(lb_huella_der) <> 1 or isnull(lb_huella_der) then
setnull(lb_huella_der)
p_der.SetPicture(lb_huella_der)
else
p_der.show( )
end if



IF p_izq.SetPicture(lb_huella_izq) <> 1 or isnull(lb_huella_izq) then
setnull(lb_huella_izq)
p_izq.SetPicture(lb_huella_izq)
else
p_izq.show( )
end if

SetPointer( Arrow! )
end if
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problema con selectblob

Publicado por Marcelo (2 intervenciones) el 25/09/2009 19:10:00
Muchas gracias por tu respuesta, te comento que el código que me envias es igual al que uso, trabajo con pb 10.5 y sybase ase y no me funciona, debe ser el tipo de dato o algo extra porque con vb.net si me despliega las imágenes del mismo sybase ase.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problema con selectblob

Publicado por miguel (153 intervenciones) el 26/09/2009 12:36:10
intenta escribir los blobs recuperados hacia un archivo en disco y mira si los puedes abrir con un programa de gráficos. (paint, photoshop, xnview, etc.). Posiblemente te dará una indicación más sobre lo que puede estár mal.

puedes hacer una comparación (fc.exe o mejor con un editor hexadecimal) de :

- una imágen que tienes en disco
- la lees con powerbuilder into Blob y la guardas en tu base de datos
- la recuperas de la base de datos con selectblob y esto lo guardas en disco con otro nombre (para poder comparar el original con lo que has recuperado).
---------------------------------------------------------------------------------------------------------------
para escribir el blob a disco puede usar la función FileWrite( ) de powerbuilder pero tendrás que hacerlo en bloques de 32kb y eso lo hace bastante lento si el archivo es de mayor tamaño. una opción mucha mejor es usar la api WriteFile( ) de windows:

// declaración de 'external funcions'
Function ulong CreateFile ( &
string lpFileName, &
ulong dwDesiredAccess, &
ulong dwShareMode, &
ulong lpSecurityAttributes, &
ulong dwCreationDisposition, &
ulong dwFlagsAndAttributes, &
ulong hTemplateFile &
) Library "kernel32.dll" Alias For "CreateFileA"
Function boolean CloseHandle ( &
ulong hObject &
) Library "kernel32.dll"
Function boolean WriteFile ( &
ulong hFile, &
Ref blob lpBuffer, &
ulong nNumberOfBytesToRead, &
Ref ulong lpNumberOfBytesRead, &
ulong lpOverlapped &
) Library "kernel32.dll"
--------------------------------------------------------------------------------
os adjunto código que escribe un blob de golpe a disco, haciendo uso de las anteriores apis:
---------------------------------------------------------------------------------
Constant ULong INVALID_HANDLE_VALUE = -1
Constant ULong GENERIC_READ = 2147483648
Constant ULong GENERIC_WRITE = 1073741824
Constant ULong FILE_SHARE_READ = 1
Constant ULong FILE_SHARE_WRITE = 2
Constant ULong CREATE_NEW = 1
Constant ULong CREATE_ALWAYS = 2
Constant ULong OPEN_EXISTING = 3
Constant ULong OPEN_ALWAYS = 4
Constant ULong TRUNCATE_EXISTING = 5

ULong lul_file, lul_bytes, lul_length
Blob lblob_filedata
Boolean lb_result
String ls_winFile, ls_fname

// IMPORTANTE: writefile tiene una limitación de 65kb (en vez de 1GB), cuando NO se
// escribe en el mismo disco. (no estoy seguro del límite superior de 1GB, creo que
// se pueden escribir archivos de más tamaño pero habrá que adapter el
// valor de GENERIC_WRITE
// entonces cuidado: si as_filename es en algún sitio de red, se limita el tamaño
// máximo a 65kb
// tiene que ser siempre un archivo en C: como por ejemplo el dir. temporal de
// windows, luego Mover hacia donde sea as_filename. con MoveFileExA()

string ls_winFile = 'C:\temp\mi_imagen_recuperado.jpg'

// tu recuperación de base de datos del blob
SELECTBLOB .... into :lblob_filedata FROM ... .ETC.

// open file for write
lul_file = CreateFile(ls_winFile, GENERIC_WRITE, &
FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0)
If lul_file = INVALID_HANDLE_VALUE Then
Return False
End If

// write the entire file contents in one shot
// creo que el límite está en un GigaByte: GENERIC_WRITE
lb_result = WriteFile(lul_file, ablob_data, &
lul_length, lul_bytes, 0)

// close the file
CloseHandle(lul_file)

if not lb_result then
return false
end if

return true

-----------------------------------
Espero que lo solucionas, una vez tuve problemas al visualizar imágenes
usando una OCX de kodak. Resultó que no se visualizaban unos imágenes recuperados de una cámera digital por la versión del bmp. cuando lo guardabamos primero con el paint de windows, sí se visualizaban bien. Problema de que la versión del formato bmp no se reconocia en el ocx ya más antiguo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problema con selectblob

Publicado por Marcelo Aguirre (21 intervenciones) el 28/10/2009 15:44:08
Hola:
Saben tengo un problema similar, cuando voy grabar un archivo pdf en la base de datos, no envia ningun error pero cuando lo quiero recuperar no lo recupera, esto sucede siempre y cuando el largo de la variable BLOB en donde se encuentra el archivo pdf es mayor a 65530, de lo contrario funciona sin ningun problema. A continuacion dejare el codigo con el cual genero el archivo pdf, con el que guardo en la base de datos y con el que recupera la imagen de la base de datos.

Datos a tener en cuenta: power builder 11.1, Sql server 2000, tipo dato del campo donde guardo el archivo es IMAGE.

/****************************************************************************************/
Codigo con el cual genero el archivo pdf y lo deja en el directorio C:\, esto lo realiza sin ningun problema siempre:

//Metodo Distiller
Int li_resp
String Nombre_Fichero
dw_preliminar2.Object.DataWindow.Export.PDF.Method = Distill!
dw_preliminar2.Object.DataWindow.Printer = "PDF995"
dw_preliminar2.Object.DataWindow.Export.PDF.Distill.CustomPostScript="Yes"
nombre_fichero = "C:\documento.pdf"
li_resp=dw_preliminar2.SaveAs(nombre_fichero, PDF!, true)

/****************************************************************************************/
Codigo con el cual grabo en la base de datos:

blob lbl_data, lbl_temp,bb_nulo
long ll_file

ll_file = FileOpen("c:\documento.pdf",streammode!)

Do While FileRead(ll_file,lbl_temp) > 0
lbl_data += lbl_temp
Loop

FileClose(ll_file)

bb_nulo = Blob('0x424DDAC9000000000000360000002800000076000000910000000100180000000000A4C90000CE0E0000D80E00000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF')

SQLCA.AutoCommit = false

delete from medios.dbo.IMAGEN_PORTAFOLIO_VIRTUAL
where por_correlativo = :ii_por
using sqlca;

if SQLCA.SQLCode <>0 then
MessageBox("Atención",'Error al Eliminar Documento Convenio Honorario~r'+SQLCA.SQLErrText,Information!)
rollback using sqlca;
sqlca.autocommit = TRUE
return
end if

select isnull(max(id_tabla),0)+1 into :si_ipo
from TABLA_IMAGEN (nolock);

INSERT INTO TABLA_IMAGEN(id_tabla,imagen)
VALUES ( :si_ipo, bb_nulo ) Using Sqlca;

If Sqlca.Sqlcode <> 0 then
Messagebox("Error de la Base de Datos", "Se ha Producido un Error al Insertar. "+ sqlca.SQLErrText , StopSign!)
Rollback Using sqlca;
sqlca.autocommit = TRUE
Return
End If

UPDATEBLOB TABLA_IMAGEN
SET imagen = :lbl_data
where id_tabla = :si_ipo
using sqlca;

if SQLCA.SQLCode <>0 then
MessageBox("SQL error",SQLCA.SQLErrText,Information!)
Rollback Using sqlca;
sqlca.autocommit = TRUE
Return
end if

FileDelete("c:\documento.pdf")
Commit using sqlca;
sqlca.autocommit = TRUE

/****************************************************************************************/
Codigo con el cual recupero la imagen de la base de datos y la dejo en C:\:

blob lbl_data
blob lbl_temp
long ll_file, ll_long = 0, ll_tam
integer li_pos = 1, si_ipo

select max(id_tabla) into :si_ipo
FROM TABLA_IMAGEN ;

if si_ipo = 0 then
messagebox('Atención','No existe Documento registrado para esta plantilla')
return
end if

SELECTBLOB imagen INTO :lbl_data
FROM TABLA_IMAGEN
where id_tabla= :si_ipo;

is_file = "c:\pdf1.pdf"

ll_file = FileOpen(is_file,StreamMode!,Write!)

ll_tam = len(lbl_data)
if ll_tam <= 32766 then
FileWrite(ll_file,lbl_data)
else
Do
lbl_temp = BlobMid(lbl_data,li_pos,32765)
ll_long = ll_long + FileWrite(ll_file,lbl_temp)
li_pos = li_pos + 32765
Loop While ll_long <= ll_tam
end if

FileClose(ll_file)

/****************************************************************************************/

Ojala alguien me pueda ayudar, ya que e buscar por todas partes y no e encontrado nada.
Saludos y Gracias
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Problema con selectblob

Publicado por Alexander Enrique Escobar (1 intervención) el 05/11/2009 17:34:47
Hola estimado

envio copy de Ayuda de PB.
========================================
FileWrite writes its data at the position identified by the file pointer. If the file was opened with the writemode argument set to Replace!, the file pointer is initially at the beginning of the file. After each call to FileWrite, the pointer is immediately after the last write. If the file was opened with the writemode argument set to Append!, the file pointer is initially at the end of the file and moves to the end of the file after each write.
FileWrite sets the file pointer following the last character written. If the file was opened in line mode, FileWrite writes a carriage return (CR) and linefeed (LF) after the last character in variable and places the file pointer after the CR and LF.

Length limit FileWrite can write only 32,766 bytes at a time, which includes the string terminator character. If the length of variable exceeds 32,765, FileWrite writes the first 32,765 characters and returns 32,765.
Unicode version of PowerBuilder If a file is opened in Line mode in the Unicode version of PowerBuilder, FileWrite writes out the file as a Unicode file if it was a Unicode file or as an ANSI file if it was an ANSI file. A new file is written out as a Unicode file. If a file is opened in Stream mode, FileWrite writes out the file as a binary file.
========================================

Claramente dice cual es el maximo permitido para el FileWrite.

Una forma de solucionarlo es usar el Mid, substring y BlobMid

otra cuestion noto que en tu sentencia incluyes el limite permitido, cuando deviera ser MENOR.

saludos cordiales.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar