Imagenes en oracle
Como hago para leer una imagen contenida en un campo blob de Oracle y mostrarlo en un formulario diseñado en asp.
Alex
Alex
1 Respuesta
Respuesta de neosys
1
1
neosys, Desde versiones 6 de experiencia en entornos ORACLE (1990)
Aunque toco muy poco el tema de 'ASP, s' y '.NET', intentaré mostrártelo con un ejemplo ... A ver si te sirve. Adáptalo y veras que fácil.
El siguiente ejemplo construye una cabecera en HTTP (HTTP header) a patir de una imagen guardada en formato binario en la BB. DD. :
file: showimg.asp
<%@ LANGUAGE="VBSCRIPT" %>
<%
' Clear out the existing HTTP header information
Response.Expires = 0
Response.Buffer = TRUE
Response.Clear
' Change the HTTP header to reflect that an image is being passed.
Response.ContentType = "image/gif"
Set cn = Server.CreateObject("ADODB.Connection")
' Asume que tienes definido el System DataSource
' por el nombre myDSN.
' Cambialos por los correctos y de Oracle.
cn.Open "DSN=myDSN;UID=<username>;PWD=<strong password>;DATABASE=pubs"
Set rs = cn.Execute("SELECT logo FROM pub_info WHERE pub_id='0736'")
Response.BinaryWrite rs("logo")
Response.End
%>
Este 'script' únicamente está definido para mostrar la imagen en una pantalla. Si la quieres mostrar en "HTML o documento ASP" tan sólo hay que hacer referencia a este como 'tag'. Por ejemplo : if you wished to display this image with a caption describing it, you might use the following HTML page:
<HTML>
<HEAD><TITLE>Display Image</TITLE></HEAD>
<BODY>
Esta pagina muestra una Imagen desde Oracle <BR>
<IMG SRC="SHOWIMG.ASP">
</BODY>
</HTML>
Y ya está ... Ejemplo de conexión te lo he puesto para SQLServer ... pero sólo tienes que cambiarlo para el DSN de Oracle y su conector.
Espero que lo entiendas y ya me contarás como te ha ido.
El siguiente ejemplo construye una cabecera en HTTP (HTTP header) a patir de una imagen guardada en formato binario en la BB. DD. :
file: showimg.asp
<%@ LANGUAGE="VBSCRIPT" %>
<%
' Clear out the existing HTTP header information
Response.Expires = 0
Response.Buffer = TRUE
Response.Clear
' Change the HTTP header to reflect that an image is being passed.
Response.ContentType = "image/gif"
Set cn = Server.CreateObject("ADODB.Connection")
' Asume que tienes definido el System DataSource
' por el nombre myDSN.
' Cambialos por los correctos y de Oracle.
cn.Open "DSN=myDSN;UID=<username>;PWD=<strong password>;DATABASE=pubs"
Set rs = cn.Execute("SELECT logo FROM pub_info WHERE pub_id='0736'")
Response.BinaryWrite rs("logo")
Response.End
%>
Este 'script' únicamente está definido para mostrar la imagen en una pantalla. Si la quieres mostrar en "HTML o documento ASP" tan sólo hay que hacer referencia a este como 'tag'. Por ejemplo : if you wished to display this image with a caption describing it, you might use the following HTML page:
<HTML>
<HEAD><TITLE>Display Image</TITLE></HEAD>
<BODY>
Esta pagina muestra una Imagen desde Oracle <BR>
<IMG SRC="SHOWIMG.ASP">
</BODY>
</HTML>
Y ya está ... Ejemplo de conexión te lo he puesto para SQLServer ... pero sólo tienes que cambiarlo para el DSN de Oracle y su conector.
Espero que lo entiendas y ya me contarás como te ha ido.
Estoy trabajando con un programador en ASP y el me pide que desde oracle le guarde en magnetivo el archivo *.TIF, el cual esta grabado en la base de datos, el procedimiento que he creado es este:
create or replace procedure leer_img(p_id number,p_file varchar2)
is
vblob blob;
length number;
buffer raw(32767);
buffer_size binary_integer := 32767;
offset number := 1;
f_lob utl_file.file_type;
Begin
SELECT imagen into vblob from tp_firma_sello
where id_registro='00000001' AND id_funcionario='00001' and id_imagen='001';
length := dbms_lob.getlength(vblob);
dbms_lob.open(vblob,dbms_lob.lob_readonly);
f_lob:=utl_file.fopen('IMAGEN_DIR',p_file,'w',32767);
While (offset <= length) loop
dbms_output.put_line(' Star :'||to_char(offset));
dbms_lob.read(vblob, buffer_size, offset, buffer);
offset := offset + buffer_size;
--utl_file.put_raw(f_lob,buffer);
End loop;
utl_file.put_raw(f_lob,buffer);
utl_file.fclose(f_lob);
dbms_lob.close(vblob);
end;
Luego de guardado en una carpeta indicada en IMAGEN_DIR el sólo leerá este archivo y lo mostrará en un formulario... este procedimiento efectivamente genera el archivo (de blob a binario) y lo guarda en la carpeta indicada pero al abrirlo no muestra la imagen, al parecer no termina de generarlo bien o es que el buffer no esta almacenando adecuadamente las direcciones de memoria... ¿o me equivoco? Podrías apoyarme por favor..
create or replace procedure leer_img(p_id number,p_file varchar2)
is
vblob blob;
length number;
buffer raw(32767);
buffer_size binary_integer := 32767;
offset number := 1;
f_lob utl_file.file_type;
Begin
SELECT imagen into vblob from tp_firma_sello
where id_registro='00000001' AND id_funcionario='00001' and id_imagen='001';
length := dbms_lob.getlength(vblob);
dbms_lob.open(vblob,dbms_lob.lob_readonly);
f_lob:=utl_file.fopen('IMAGEN_DIR',p_file,'w',32767);
While (offset <= length) loop
dbms_output.put_line(' Star :'||to_char(offset));
dbms_lob.read(vblob, buffer_size, offset, buffer);
offset := offset + buffer_size;
--utl_file.put_raw(f_lob,buffer);
End loop;
utl_file.put_raw(f_lob,buffer);
utl_file.fclose(f_lob);
dbms_lob.close(vblob);
end;
Luego de guardado en una carpeta indicada en IMAGEN_DIR el sólo leerá este archivo y lo mostrará en un formulario... este procedimiento efectivamente genera el archivo (de blob a binario) y lo guarda en la carpeta indicada pero al abrirlo no muestra la imagen, al parecer no termina de generarlo bien o es que el buffer no esta almacenando adecuadamente las direcciones de memoria... ¿o me equivoco? Podrías apoyarme por favor..
Creo que a la pregunta le habéis dado la vuelta y habéis optado por que se haga todo desde PL/SQL y no en .ASP como me indicasteis.
Ahora tendréis el problema de gestionar los ficheros resultantes ... pero ...
"Recuerdo que no hace mucho, generábamos códigos de barra en J2EE y luego lo mostrábamos en ORACLE REPORTS. Cuando la máquina estaba totalmente libre, no nos mostraba el gráfico con el código de barras. Y es que creer que al lanzar un proceso en Oracle y después otro, han de ser consecutivos y secuenciales, y muchas veces no es así. Y Oracle deja como tarea pendiente en sistemas mutitarea la ejecución de sus procesos internos. y más con la grabación de ficheros".
Aún así. He observado el código, y para mi que te falta el 'FLUSH' que es un volcado de todo lo que tienes en CACHE a Disco.
Os envío un ejemplo que tenia por ahí ... Espero que os sirva. Hace uso de cursores, pero ni caso.
Un Saludo y ya me comentareis si hay algún problema.
Ramón - BCN
NOTA : Si veis que no se ve, comprobar los privilegios y luego haced una página HTML sencilla que apunte a este fichero a ver si se ve. (Sobre todo mucho cuidado también con los privilegios de lectura escritura por el mismo o diferentes usuarios!).
- Si aún así no os sale nada, posiblemente se haya grabado mal la imagen en ORACLE.
Revisar el proceso de grabación.
============================================================
DECLARE
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
BEGIN
-- Get LOB locator
SELECT BLOB_COLUMN
INTO l_blob
FROM B_FILE
WHERE id = 4;
l_blob_len := DBMS_LOB.getlength(l_blob);
l_file := UTL_FILE.fopen('REEDIR','MyImage.jpg','w', 32767);
WHILE l_pos < l_blob_len LOOP
DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_file, l_buffer, TRUE);
l_pos := l_pos + l_amount;
UTL_FILE.FFLUSH(file => l_file);
END LOOP;
UTL_FILE.fclose(l_file);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
RAISE;
END;
/
¿Ya me contareis?
Ahora tendréis el problema de gestionar los ficheros resultantes ... pero ...
"Recuerdo que no hace mucho, generábamos códigos de barra en J2EE y luego lo mostrábamos en ORACLE REPORTS. Cuando la máquina estaba totalmente libre, no nos mostraba el gráfico con el código de barras. Y es que creer que al lanzar un proceso en Oracle y después otro, han de ser consecutivos y secuenciales, y muchas veces no es así. Y Oracle deja como tarea pendiente en sistemas mutitarea la ejecución de sus procesos internos. y más con la grabación de ficheros".
Aún así. He observado el código, y para mi que te falta el 'FLUSH' que es un volcado de todo lo que tienes en CACHE a Disco.
Os envío un ejemplo que tenia por ahí ... Espero que os sirva. Hace uso de cursores, pero ni caso.
Un Saludo y ya me comentareis si hay algún problema.
Ramón - BCN
NOTA : Si veis que no se ve, comprobar los privilegios y luego haced una página HTML sencilla que apunte a este fichero a ver si se ve. (Sobre todo mucho cuidado también con los privilegios de lectura escritura por el mismo o diferentes usuarios!).
- Si aún así no os sale nada, posiblemente se haya grabado mal la imagen en ORACLE.
Revisar el proceso de grabación.
============================================================
DECLARE
l_file UTL_FILE.FILE_TYPE;
l_buffer RAW(32767);
l_amount BINARY_INTEGER := 32767;
l_pos INTEGER := 1;
l_blob BLOB;
l_blob_len INTEGER;
BEGIN
-- Get LOB locator
SELECT BLOB_COLUMN
INTO l_blob
FROM B_FILE
WHERE id = 4;
l_blob_len := DBMS_LOB.getlength(l_blob);
l_file := UTL_FILE.fopen('REEDIR','MyImage.jpg','w', 32767);
WHILE l_pos < l_blob_len LOOP
DBMS_LOB.read(l_blob, l_amount, l_pos, l_buffer);
UTL_FILE.put_raw(l_file, l_buffer, TRUE);
l_pos := l_pos + l_amount;
UTL_FILE.FFLUSH(file => l_file);
END LOOP;
UTL_FILE.fclose(l_file);
EXCEPTION
WHEN OTHERS THEN
IF UTL_FILE.is_open(l_file) THEN
UTL_FILE.fclose(l_file);
END IF;
RAISE;
END;
/
¿Ya me contareis?
Al ejecutarlo me arroja el siguiente error:
SQL> exec leer_img2;
begin leer_img2; end;
ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
ORA-06512: at "SOPORTE.LEER_IMG2", line 33
ORA-06512: at line 1
Y la linea 33 es :
Riaser;
Lo único que he cambiado es la lectura del archivo que está en mi tabla, el campo (imagen) es del tipo log raw, y es aquí donde tengo almacenada mi imagen. Trabajo con Oracle 9i no creo que ello sea mayor problema.
SELECT imagen
into l_blob
from tp_firma_sello
where id_registro='00000001'
AND id_funcionario='00001'
and id_imagen='001';
Ahora quitando la linea RAISER, me arroja que se ha ecutado sin problemas, pero la imagen no la ubico por ningún lado, en la carpeta donde apunta mi objecto DIRECTORY
Saludos,
Alex
SQL> exec leer_img2;
begin leer_img2; end;
ORA-00932: inconsistent datatypes: expected NUMBER got BINARY
ORA-06512: at "SOPORTE.LEER_IMG2", line 33
ORA-06512: at line 1
Y la linea 33 es :
Riaser;
Lo único que he cambiado es la lectura del archivo que está en mi tabla, el campo (imagen) es del tipo log raw, y es aquí donde tengo almacenada mi imagen. Trabajo con Oracle 9i no creo que ello sea mayor problema.
SELECT imagen
into l_blob
from tp_firma_sello
where id_registro='00000001'
AND id_funcionario='00001'
and id_imagen='001';
Ahora quitando la linea RAISER, me arroja que se ha ecutado sin problemas, pero la imagen no la ubico por ningún lado, en la carpeta donde apunta mi objecto DIRECTORY
Saludos,
Alex
Lo siento, no te lo indiqué!
No uses para nada el tipo LONG RAW!
Usa Blog!
Sorry por los errores, pero los has detectado correctamente.
Un Saludo
Nota : No sé si tienes el ORACLE en linux, o unix, pero asegurate de que puedes escribir en ese directorio que has definido como objeto de BB. DD. Y si estás en UNIX te lo dejará como co nprivilegio de ORACLE. Ya que aunque lo ejecutes con otro usuario. Siempre será propiedad de ORACLE.
Coloca por si acaso en el :
When others then
dbms_output.put_line( sqlerrm );
Colocando antes de ejecutarlo : SET SERVEROUTPUT ON
No uses para nada el tipo LONG RAW!
Usa Blog!
Sorry por los errores, pero los has detectado correctamente.
Un Saludo
Nota : No sé si tienes el ORACLE en linux, o unix, pero asegurate de que puedes escribir en ese directorio que has definido como objeto de BB. DD. Y si estás en UNIX te lo dejará como co nprivilegio de ORACLE. Ya que aunque lo ejecutes con otro usuario. Siempre será propiedad de ORACLE.
Coloca por si acaso en el :
When others then
dbms_output.put_line( sqlerrm );
Colocando antes de ejecutarlo : SET SERVEROUTPUT ON
Hola experto, disculpa por no haber respondido, pero te comento que ya graba el archivo extraído de la BD, pero no contiene imagen, podría ser por que falta darle los permisos necesario al directorio del servidor para poder grabar... trabajo con Windows 2003. ¿Alguna otra recomendación?
Gracias por tu invalouable apoyo
Alex
Gracias por tu invalouable apoyo
Alex
- Compartir respuesta
- Anónimo
ahora mismo