ORACLE: Importar CLOBS

¿Cómo importar CLOBS en Oracle?

Si probamos de hacer un export desde el SQLDeveloper, veremos que solamente podemos exportar la estructura de la tabla sin poder volver a recrear el contenido del CLOB. Seguramente una vez llegados a este punto, decidamos realizar un export mediante las utilidades EXP/IMP. Si intentamos esto nos encontraremos con la sorpresa que para poder recrear la tabla, si no tenemos el mismo TABLESPACE creado en la BD destino no nos dejará crear la tabla dándonos el siguiente error:

ORA-00959: tablespace 'XXXXX' does not exist

Después de darle varias vueltas he encontrado una solución y es la siguiente:

1) Hacer export mediante comando EXP, por ejemplo:

EXP schema_origen/pass OWNER=schema_orgien FILE=file_destino.dmp DIRECT=Y ROWS=Y LOG=file.log

2) Crear la estructura de la tabla mediante DDL:

CREATE TABLE tabla (col1 tipo, ....)

Nota: La estructura debe ser la misma que en la de la tabla en el export

3) Realizar un import con el flag IGNORE=Y

IMP USERID=schema_destino/pass FROMUSER=schema_origen/pass TOUSER=schema_destino file=file_destino.dmp LOG=file_import.log TABLES=nombre_tabla IGNORE=Y

Fuente de la notícia con la explicación técnica detallada:

http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:66890284723848

APEX Printing PDF reports using COCOON instead of BI Publisher

Since I think this can be quite useful I’ll write it down in English.

I’ve followed the steps proposed by Carl Backstorm but I’m going to install it in a Linux Server (Ubuntu 8.04).

Files needed:

Cocoon 2.1.11
Tomcat 6
fop_post.zip

Download and decompress them all.

1) Download and decompress cocoon-2.1.11
2) Check JAVA is installed (I installed jdk6) and
be sure JAVA_HOME is set to your actual location:

$ export JAVA_HOME=/usr/

Go to the decompressed folder (cocoon-2.1.11/) and execute:

$ ./build.sh war

3) Notice where cocoon.war was built:

cocoon-2.1.11/build/cocoon

4) Copy cocoon.ware to tomcat in webapps directory

apache-tomcat-6.0.18/webapps/

5) Copy fop_post folder to

apache-tomcat-6.0.18/webapps/cocoon/

6) Start apache tomcat:

Before doing that, you may want to change apache port in order to avoid conflicts with APEX port.
You can change apache 8080 port to 8088 by editing conf/server.xml and replacing 8080 with 8088.

(locate to tomcat folder and run as root)

$ sudo ./bin/startup.sh

7) Check installation is right by accessing http://localhost:8088/cocoon

8) Now, let’s configure APEX in order to be able to print reports in PDF using cocoon:
8.1) Login with internal APEX account
8.2) Go to Manage Service -> Instance Settings -> Report Printing
8.3) Change to new configuration
Print Server Host Address: localhost
Print Server Port: 8088
Print Server Script: /cocoon/fop_post/

9) You may want to start cocoon automatically at startup. Then you can create a file under /etc/init.d like the following one:

/etc/init.d/cocoon.sh

1
2
3
4
#!/bin/bash
JAVA_HOME=/usr/
echo "Starting Apache Cocoon..."
/opt/apache-tomcat-6.0.18/bin/startup.sh

Make it executable

$ sudo chmod +x /etc/bin/cocoon.sh

and add it in your boot process:

$ update-rc.d cocoon.sh defaults

Hope it helps!!

Further information:
http://carlback.blogspot.com/2007/03/apex-cocoon-pdf-and-more.html

ORACLE: Compile all invalid objects

Para compilar los objetos inválidos del usuario de BD actual podemos ejecutar el siguiente script:

1
2
3
4
5
6
7
8
SELECT 'ALTER '
  ||decode(object_type,'PACKAGE BODY','PACKAGE',object_type)
  ||' '
  ||object_name
  ||decode(object_type,'PACKAGE BODY', ' COMPILE BODY;',' COMPILE;')
   FROM user_objects
  WHERE STATUS   = 'INVALID'
AND object_type IN ('PACKAGE','PACKAGE BODY','FUNCTION','PROCEDURE');

Esto nos generará una serie de alters para poder recompilar los objetos inválidos.

Oracle: Script para hacer un drop de all user objects

Un ejemplo de script para hacer un drop de todos los objetos del usuario seria el siguiente:

1
2
3
4
5
6
7
8
9
SELECT 'drop sequence ' || sequence_name || ';' FROM user_sequences
UNION
SELECT 'drop trigger ' || trigger_name || ';' FROM user_triggers
UNION
SELECT 'drop view ' || view_name || ';' FROM user_views
UNION
SELECT 'drop index ' || index_name || ';' FROM user_indexes
UNION
SELECT 'drop table ' || table_name || ';' FROM user_tables;

De momento solamente hace drops de triggers, vistas, índices y tablas pero se puede añadir unions para generar el drop de lo que queramos.

Una vez ejecutada la consulta, copiar el resultado en una hoja de SQL y ejecutarla. Es posible que nos den errores por dependencias y no se borren todos los objetos, en ese caso lo que hago es ejecutar el script varias veces hasta que se borren todos los objetos (se debería hacer una nueva versión que calcule las dependencias pero eso ya seria demasiado tiempo…)

Instalar Oracle XE 10g + APEX 3.1.2 en VirtualBox 2.0.2 con Ubuntu 8.04

Después de pelearme un buen rato he conseguido instalar una máquina virtual con APEX 3.1.2 de modo que sea totalmente accesible desde la máquina host, de modo que solamente con arrancar la máquina virtual ya tengo acceso a una instalación APEX sin ensuciar mi SO host.

Instalación

1) Instalación de VirtualBox

En mi caso particular, mi equipo Host también es un Ubuntu 8.04. Podéis instalaros la VirtualBox bajándoos el .deb de la página o bién añadiendo la siguiente línea en vuestro /etc/apt/sources.list:

deb http://download.virtualbox.org/virtualbox/debian hardy non-free

luego podemos instalar desde Synaptics nuestro VirtualBox 2.0.2 (solamente es necesario descargar los módulos genéricos).

2) Creación de la máquina Virtual en VirtualBox:

Yo os aconsejaría crear dos discos virtuales:

- 8GB -> Para Instalación de Ubuntu + APEX
- 1,5GB -> Memoria SWAP (no uséis menos de 1024MB porqué sinó no podréis instalar la Oracle XE)

A continuación realizar la instalación de Ubuntu en la máquina virtual.

3) Instalación de Oracle XE:

Nos bajamos la última versión de Oracle Express Edition 10g (XE) para Linux de www.oracle.com

Suponiendo que nos hemos bajado la versión oracle-xe_10.2.0.1-1.0_i386.deb, nos ubicamos en el directorio donde esté el fichero y ejecutamos:

$ sudo dkpg -i oracle-xe_10.2.0.1-1.0_i386.deb

Una vez termine, ejecutamos los pasos de configuración:

$ sudo /etc/init.d/oracle-xe configure

Yo he dejado todos los valores por defecto.

4) Instalación de APEX 3.1.2

Nos bajamos la última versión de APEX en http://apex.oracle.com y la descomprimimos en algún sitio.
Ahora será necesario ejecutar unos scripts desde el usuario SYS mediante SQLPLUS. Si nos fijamos, la instalación nos habrá creado un nuevo tipo de usuario de SO llamado Oracle. Yo he creado un nuevo usuario de SO asociado a oracle, que he llamado también oracle (con password: oracle).

En primer lugar debemos cambiar al usuario de SO administrador de Oracle:

$ su oracle

Ahora debemos cargar las variables de entorno para conseguir un buen funcionamiento de la instalación de APEX. Para ello podemos ejecutar:

export TMP=/tmp
export TMPDIR=/tmp
export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
export PATH=/usr/bin:$ORACLE_HOME/opmn/bin:$ORACLE_HOME/bin:${PATH}
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib:$ORACLE_HOME/network/jlib
export ORACLE_SID=XE
export TNS_ADMIN=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/network/admin

y con esto ya tenemos las variables de entorno inicializadas (si no habéis tocado ningún parámetro debería funcionaros a la perfección, sino revisad los directorios).

Importante: Nos ubicamos en el directorio donde hayamos descomprimido el ZIP de instalación de APEX. Dentro de ese directorio deben haber los ficheros apexins.sql, apxxepwd.sql, etc.
Nos conectamos a sqlplus con modo sys:

$ sqlplus /nolog
SQL*Plus: Release 10.2.0.1.0 - Production ON Thu Oct 9 18:56:14 2008
 
Copyright (c) 1982, 2005, Oracle.  ALL rights reserved.
 
SQL> conn / AS sysdba
Connected.

Ejecutamos el primer script de instalación:

SQL> @apexins PASSWORD  SYSAUX SYSAUX TEMP /i/

Nota: Cambiamos PASSWORD por el password que hayamos asignado en el paso 3
Si no se ha producido ningún error continuamos con el siguiente paso, que es cambiar el password del workspace internal:

 SQL> @apxxepwd.sql

Nos pedirá un password para posteriormente poder acceder al workspace: internal con usuario admin.

El siguiente paso hace un update de las imágenes:

 SQL> @apxldimg.sql APEX_INSTALL

Nota: Cambiamos APEX_INSTALL por el directorio donde hayamos descomprimido el ZIP de instalación. Hay que poner la ruta completa.

5) Si todo ha ido bien, ya deberíamos poder acceder a nuestra nueva instalación de APEX escribiendo en un navegador la siguiente dirección:

http://localhost:8080/apex

Configuración para poder acceder remotamente

Ahora vamos a configurar nuestro entorno de modo que podamos acceder a nuestro entorno desde fuera de la máquina virtual (por ejemplo desde el SO Host).

1) Ejecutamos el siguiente comando desde sqlplus como usuario SYS (loguearnos como en el paso 4):

SQL> EXEC DBMS_XDB.SETLISTENERLOCALACCESS(FALSE);
 
PL/SQL procedure successfully completed.

Con esto permitimos conexiones remotas a APEX.

2) Ahora apagamos nuestra máquina virtual. Una vez completamente apagada, vamos a editar el XML asociado a nuestra máquina virtual para hacer un port forwarding de los puertos que queremos redirigir de nuestra máquina guest a nuestra máquina host. Normalmente el fichero xml asociado acostumbra a estar en nuestro home: /home/usuario/.VirtualBox/Machines/NOMBRE/fichero.xml

Abrimos el fichero y añadimos las siguientes lineas dentro del tag :

<ExtraDataItem name="VBoxInternal/Devices/pcnet/0/LUN#0/Config/httpd/GuestPort" value="8080"/>
<ExtraDataItem name="VBoxInternal/Devices/pcnet/0/LUN#0/Config/httpd/HostPort" value="8080"/>
<ExtraDataItem name="VBoxInternal/Devices/pcnet/0/LUN#0/Config/oraclexe/Protocol" value="TCP"/>
<ExtraDataItem name="VBoxInternal/Devices/pcnet/0/LUN#0/Config/oraclexe/GuestPort" value="1521"/>
<ExtraDataItem name="VBoxInternal/Devices/pcnet/0/LUN#0/Config/oraclexe/HostPort" value="1521"/>

Nota: Esto también se puede hacer por medio del comando

VBoxManage setextradata …

Volvemos a encender nuestra máquina virtual.

Una vez encendida, podemos verificar que tenemos acceso si intentamos navegar desde nuestro SO Host a la dirección:

http://localhost:8080/apex

Espero que os sirva!!!
PD: Como recibo mucho spam, si no os contesto podéis enviarme un email a: josepcoves(arroba)gmail.com

Fuentes usadas:

http://www.oracle.com/technology/products/database/application_express/html/3.1_and_xe.html

http://download.oracle.com/docs/cd/B32472_01/doc/install.300/b32468/install.htm#CHDHIJGE

http://download-east.oracle.com/docs/cd/B25329_01/doc/admin.102/b25107/network.htm#BHCBCFBA

http://www.virtualbox.org/

APEX: Obtener un contador de errores de validaciones en PLSQL

Para saber si se han producido errores de validación, podemos usar la siguiente llamada:

NVL(apex_application.g_inline_validation_error_cnt,0)

que nos devuelve un count del número de validaciones que han terminado en error.

PLSQL: Cómo recojer valores checkbox de un formulario HTML

Cuando tenemos que recojer diversos valores de checkbox en un formulario HTML, normalmente nos encontramos con que el identificador del elemento HTML es el mismo, cosa que realiza una concatenación de valores por GET o POST con el mismo identificador. Algunos lenguajes de programación facilitan la recolección de dichos valores generando un array de valores (por ejemplo PHP). En el caso de PLSQL esta funcionalidad no está desarrollada por defecto, pero podemos escribir un código que nos realice la misma funcionalidad:

 
CREATE OR REPLACE PACKAGE pkg_checkboxes IS
 
TYPE chkArray IS TABLE OF VARCHAR2(100) INDEX BY BINARY_INTEGER;
PROCEDURE display_form;
PROCEDURE process_form(checkboxes IN VARCHAR2 DEFAULT NULL);
PROCEDURE process_form(checkboxes IN chkArray);
 
END pkg_checkboxes;
 
CREATE OR REPLACE PACKAGE BODY pkg_checkboxes IS
 
PROCEDURE display_form IS
BEGIN
htp.p('<html>');
htp.p('<head>');
htp.p('<title>Checkboxes Testing</title>');
htp.p('</head>');
htp.p('<body>');
htp.p('<form name="frmChk" method="post" action="cp_cpw_checkboxes.process_form">');
htp.p('<input type="checkbox" name="checkboxes" value="Japan" /> Japan
');
htp.p('<input type="checkbox" name="checkboxes" value="China" /> China
');
htp.p('<input type="checkbox" name="checkboxes" value="Russia" /> Russia
');
htp.p('<input type="checkbox" name="checkboxes" value="USA" /> USA
');
htp.p('<input type="checkbox" name="checkboxes" value="Canada" /> Canada
');
htp.p('
');
htp.p('<input type="submit" value="Submit" />');
htp.p('</form>');
htp.p('</body>');
htp.p('</html>');
END display_form;
 
PROCEDURE process_form(checkboxes IN VARCHAR2 DEFAULT NULL) IS
BEGIN
htp.p('You selected:
 
');
htp.p('
<ul>');
IF checkboxes IS NOT NULL THEN
htp.p('
	<li>'||checkboxes||'</li>
');
ELSE
htp.p('
	<li>No checkbox selected</li>
');
END IF;
htp.p('</ul>
');
END process_form;
 
PROCEDURE process_form(checkboxes IN chkArray) IS
BEGIN
htp.p('You selected:
 
');
htp.p('
<ul>');
FOR i IN 1..checkboxes.COUNT LOOP
htp.p('
	<li>'||checkboxes(i)||'</li>
');
END LOOP;
htp.p('</ul>
');
END process_form;
 
END pkg_checkboxes;

(Código obtenido de http://www.joelennon.com/?q=pl-sql-checkboxes)

Cómo cargar el entorno de portal en una sesión SQL

Si necesitamos acceder a las vistas de portal para realizar una query externa usando SQL plus o SQL Developer, necesitarem iniciar el entorno de Portal. Lo podemos hacer con la siguiente sentencia:

BEGIN
portal.wwctx_api_private.set_context( p_user_name => 'portal') ;
END;

Averiguar con que versión de BD Oracle estamos trabajando

Para descubrir la versión de Base de Datos Oracle con la que estamos trabajando podemos ejecutar la siguiente sentencia SQL:

SELECT * FROM SYS.V_$VERSION;

Modificar un tablespace para que sea AUTOEXTEND

ALTER database datafile
'/oracle/oradata/tablespace.dbf'
autoextend ON;