sábado, 12 de noviembre de 2011

ORA-28056: Writing audit records to Windows Event Log failed

Si se te presenta este error de oracle "ORA-28056: Writing audit records to Windows Event Log failed" es un problema relacionado al tratar de escribir en el log de eventos de windows.

ORA-28056: Writing audit records to Windows Event Log failed

Este error lo puedes solventar limpiando el log de errores de windows desde la consola administrativa que se encuentra en Herramientas Administrativas / Visor de suscesos o ejecutar el comando eventvwr.msc /s

Luego deberas borrar el log de Sistema y de Aplicación.

lunes, 7 de noviembre de 2011

¿Por qué migrar a BD Oracle 11G?


Como es de esperarse cada nueva versión de Oracle tiene muchas ventajas a la versión anterior, estas mejoras en su mayoría corresponde a mejoras en su núcleo, Administración y seguridades, estas mejoras contribuyen con herramientas, funcionalidades y utilidades para los DBA para mejorar y controlar la administración de nuestras base de datos.
Como mencioné hace un momento "En su mayoría corresponden a mejoras en su núcleo, administración y seguridades" pero esta nueva versión también beneficia a los desarrolladores.

Ahora mencionaré alguna de las nuevas características que tiene la 11g.

Browser-Based Enterprise Manager Integrated Interface for LogMiner
Es una gran utilidad implementada en 11g, que nos permite buscar dentro de los logs (Online y Archive redo log) las transacciones DML o DDL ejecutadas.

Es una buena utilidad que puede ser usada de manera gráfica o con el paquete DBMS_LOGMNR. El LogMiner Viewer forma parte del Enterprise Manager que viene en el Software Oracle Client.

Como les dije, es una excelente utilidad que nos permitirá examinar los Online/Archive redo log que es el repositorio de todos los DML y DDL ejecutados. Con esto podríamos realizar una mejor investigación para: Auditorias post-transaccion, Detectar y revisar los errores de usuarios.

DDL_LOCK_TIMEOUT
Cuando se trata de alterar una tabla esto requiere de un bloqueo exclusivo del objeto para que ninguna otra sesión trate de trabajar con la tabla que estamos modificando. ¿Pero qué pasa si intentamos alterar una tabla que está siendo bloqueada por otra sesión de usuario y no ha confirmado o desecho la transacción DML? La respuesta es simple "ORA-00054: recurso ocupado y obtenido con NOWAIT especificado", esto es lógico por que no nos dejará realizar modificaciones a la estructura si hay otras transacciones, pero el problema es que puede ser que la transacción que genera el bloque solo demore un segundo o 5 segundo, y durante ese lapso simpre nos retornara el error.

Para evitar esto, podemos configurar el DDL_LOCK_TIMEOUT a un tiempo prudente que nuestro DDL deberá esperar para poder realizar el cambio sin que nos retorne el error "ORA-00054: recurso ocupado y obtenido con NOWAIT especificado". Esto quiere decir que si tratamos de alterar la tabla y está bloqueada por otra sesión esta se espera el tiempo configurado hasta poder alterarla.
ALTER SYSTEM SET DDL_LOCK_TIMEOUT=60 SCOPE=BOTH;

En mi caso lo tengo configurado con 60 (en segundos), es decir que mi sesión esperará hasta 60 segundo para poder altera la tabla antes de que mande el error.

Índices invisibles
Con esto puedes definir que índices están o no visibles para el CBO (Optimizador Basado en Costos), con esto quiero decir que el índice sigue en constante actualización si ocurren transacciones DML sobre la tabla, pero este índice no es considerado para realizar análisis de costos al momento de realizar el plan de ejecución.

Cual es el objetivo? El objetivo es ver el rendimiento del nuevo índice con respecto a los anteriores planes de ejecución, pero no queremos que el índice entre en producción (Con esto quiero decir que no sea tomado en cuenta por el CBO).

Creación de índice invisible
CREATE INDEX Indice_01 ON MI_TABLA(CAMPO_1) INVISIBLE;

Como hacer un índice invisible a visible:
ALTER INDEX Indice_o1 VISIBLE;

Como hacer para que en nuestra sesión se consideren índice invisible en un plan de ejecución:
ALTER SESSION SET optimizer_use_invisible_indexes=TRUE;

Tablas de solo lectura (Read Only Tables)
Como su nombre lo dice, esto nos permite cambiar a modo solo lectura las tablas que deseamos (Algo así lo logramos iniciando la base de datos como solo lectura o cambiando el modo del tablespace a solo lectura)

Cambiar a solo lectura la tabla
ALTER TABLE Nombre_Tabla READ ONLY;

Cambiar a modulo lectura y escritura
ALTER TABLE Nombre_Tabla READ WRITE;

Dependencia de objetos más finas (Finer Grained Dependencies)
En versiones anteriores la 11g cuando se realizan cambios a la metadata los objetos que tienen dependencia, estos objetos dependientes son invalidados. Supongamos que tenemos la tabla Persona con el campo Nombre y Apellido, luego creamos una vista V_Persona con los campos nombre y apellido solamente, ahora si realizamos un cambio a la tabla Persona agregándole el campo edad esto causa que la vista V_Persona sea invalidad, pero si revisamos la composición de la vista esta solo tiene los campos Nombre y Apellido. Ya en 11g esto no ocurre, ya que la relación es mas fina, es decir no incluye todo el objeto, si no los campos que involucran la relación.

Mejoras al agregar columnas (Enhanced ADD COLUMN Functionality)
Todos sabemos que es un dolor de cabezas agregar un valor default a un campo y sobre todo si esta tabla tiene millones y millones de registros ya que el valor por default deberá actualizarse en todos los registros causando un problema de rendimiento.

Para evitar estos maltrechos incidentes, en la versión 11g los valores por default para campos NOT NULL se almacenaran en la metadata y no en la fila del dato. Esto mejora el rendimiento al momento de alterar el campo de una tabla indicándole el valor por defecto y no ocupará espacio en disco.

Compresión de archivos DUMP.
Ahora podemos generar archivos DUMP de metadata o datos con una compresión del 10 al 15% del lo que originalmente se generaba. Tu puedes indicar que es lo que deseas comprimir: Metadata, Datos o Ambos.

Encriptación de los archivos DUMP
Para mayor seguridad, ahora podemos generar archivos DUMP con encriptación de datos, metadatos o ambos. Esto viene incluido en esta versión 11g.

SQL PIVOT.
En esta versión 11g podremos pivotear el resultado de una consulta sobre un campo específico.

Supongamos que deseamos obtener las ventas del 09-2011 al 12-2011 para todos los clientes, pero los totales mensuales los queremos por columnas. Lo que tendríamos que hacer es utilizar combinación de SUM y DECODE / CASE WHEN para obtener los totales por mes.
SELECT CLIENTE,
SUM(case when FECHA BETWEEN TO_DATE('01-10-2011') and TO_DATE('31-10-2011') then VALOR_VENTA else 0 end) OCT,
SUM(case when FECHA BETWEEN TO_DATE('01-11-2011') and TO_DATE('30-11-2011') then VALOR_VENTA else 0 end) NOV,
SUM(case when FECHA BETWEEN TO_DATE('01-12-2011') and TO_DATE('31-12-2011') then VALOR_VENTA else 0 end) DIC
FROM VENTAS
GROUP BY CLIENTE

En 11g es mas sencillo realizar esto:
SELECT *
FROM
(    
    SELECT TO_CHAR(FECHA,'MON')MES,VALOR_VENTA
    FROM Ventas
    WHERE FECHA BETWEEN TO_DATE('01-10-2011') and TO_DATE('31-12-2011')
)
PIVOT (SUM(VALOR_VENTA) FOR MES)

Columnas Virtuales
Columnas virtuales, son columnas que depende de una expresión o formula, es decir son campos calculados con otros campos, estos datos pueden quedar solo en la definición de la metadata y no en el espacio de datos de la tabla. Imagine que tenemos la tabla Empleados don tenemos el campos Salario y Bono, el ingreso total es la suma de Salario y Bono, esto quedaría definido así:
CREATE TABLE Empleados(
identificacion     VARCHAR2(15),
nombre        VARCHAR2(30),
apellido        VARCHAR2(30),
salario        NUMBER(9,2),
bono            NUMBER(9,2),
ingreso_total AS (salario + bono)
)

Como vemos la definición de una columna virtual es sencilla, solo hay que tener en cuenta que una columna virtual tiene sus restricciones:
 Una columna virtual no puede se compuesta por otra columna virtual.
Los campos de la columna virtual deben de pertenecer a la tabla.

Asignación a una variable del nextval de una secuencia sin usar el método select into from dual
Esto nos quita la tediosa tarea de asignar a una variable el nextval de una sequencia, ahora podemos asignar directamente a una variable

Declare
  nValor number(5);
Begin
 nValor:=secuencia_empleado.nextval.nexval;
End;

jueves, 20 de octubre de 2011

Sinónimos Huérfanos


Saludos
Los objetos tipos sinónimos (Públicos o privados) en la base de datos son alias a otros objetos de base de datos, por ejemplo si tenemos una tabla CLIENTES pero queremos que se la conozca como MIS_CLIENTES lo que se haría es crear el sinónimo para la tabla clientes de la siguiente tabla:
CREATE PUBLIC SYNONYM MIS_CLIENTES FOR CLIENTES;


Ya sabemos que los sinónimos son alias a los objetos de base de datos, pero ¿que pasa si el objeto al que hace referencia le cambiamos el nombre o eliminamos el objeto, el objeto Sinónimo también cambia de manera automática su referencia?
Pues la respuesta es no, lo que sucederá es que se dará el caso de "Sinónimos huérfanos" ya que el objeto sinónimos queda en el diccionario del SYS con la referencia al objeto anterior, por lo que para evitar esto es lo recomendable es que siempre que se borre o recree los sinónimos después de que se altere el nombre o borre algún objeto, siempre que se usen sinónimos para esos objetos.
En nuestro ejemplo del alias MIS_CLIENTES, si cambiamos el nombre a la tabla CLIENTES los pasos a seguir serian los siguientes:
--Cambiamos el nombre de la tabla
ALTER TABLE CLIENTES RENAME TO A_CLIENTES;
--Recreamos el sinónimo con el nuevo nombre de la tabla
CREATE OR REPLACE PUBLIC SYNONYM MIS_CLIENTES FOR A_CLIENTES;


Ya sabemos que es lo que debemos de hacer para no dejar sinónimos huérfanos, pero ¿Cómo sabemos que no existen más sinónimos huérfanos?
El siguiente script nos retornará la cantidad de sinónimos huérfanos:
--Cantidad de sinonimos huerfanos
select s.TABLE_OWNER, count(*)Cantidad from all_synonyms s
where not exists(select 1 from all_objects o where s.TABLE_OWNER=o.OWNER and s.TABLE_NAME=o.OBJECT_NAME )
and owner not in ('SYS','SYSTEM')
group by s.TABLE_OWNER;


El siguiente script te ayudará a eliminar los sinónimos huérfanos que existan:
begin
for v in (
select decode (owner,'PUBLIC','drop public synonym '||synonym_name,'drop synonym '||owner||'.'||synonym_name)||''vsql from all_synonyms s
where not exists(select 1 from all_objects o where s.TABLE_OWNER=o.OWNER and s.TABLE_NAME=o.OBJECT_NAME )
and owner not in ('SYS','SYSTEM')
)loop
begin
execute immediate v.vsql;
exception when others then
dbms_output.put_line(v.vsql||'-'||sqlerrm);
end;
end loop;
end;


Algo que también se debe de considerar es que se pueden crear sinónimos de objetos que no existen en la base de datos.

domingo, 25 de septiembre de 2011

Forms developers Tips

DATA BLOCK PROPERTY
Database\Update Changed Columns Only

Saludos, a continuación les voy a explicar el por que es importante considerar el parámetro de bloque de datos Update Changed Columns Only.


Se debe de considerar cuando se cumplan las siguientes condiciones:
  • Es un bloque de base de datos
  • Se permite la modificación del registro
  • La tabla atachada al bloque de datos tiene primary key y otras tablas estan relacionadas a la tabla atachada al bloque.
Que valor debe de setearse y por que es importante?
El valor que debe se setearse es YES y es importante para que al momento de realizar la modificación y grabar los cambios solo se actualicen las columnas que fueron modificadas, caso contrario si el parámetro esta seteado con NO en la actualización se consideraran todos lo campos de la tabla que fueron atachados al bloque.

Bajo ningun concepto en una base de datos relacional se debería poder actualizar un campo que sea parte de una clave primaria ya que al hacerlo esto causaría el bloqueo simultaneo de datos que tengan relación con el registro(Foreing Keys).

El parámetro deberá quedar asi:

Este parametro por default es NO, y nos causo muchos problemas de bloqueos de datos ya que mientras los uausrios realizaban configuraciones estos cambios afectaban a tablas de configuración que tenian otras tablas hijas con mas de 15 millones de registros y no había indices FK en las tablas hijas por lo que se hacia un bloqueo total a las tablas hijas.

Espero les sirva y lo consideren durante sus desarrollos.

sábado, 24 de septiembre de 2011

Tunea tu Report Server Oracle 10g

A continuación este artículo les ayudara a mejorar el rendimiento y desempeño se nuestro OASR2 10.1.2 (Oracle Application Server).

Report Parameter
 Si tenemos varios usuarios que desean ejecutar reportes e informes pero se quejan que esperan mucho tiempo (porque es solo un formulario que imprimen). Lo ideal es que se optimice el reporte para ver si se le puede hacer algún tuneo a la consulta, pero si son reportes que por su naturaleza son complejos y necesitan de un tiempo de entre 10 y 60 segundos a nivel de del reporte no podemos hacer nada para mejorarlo, lo que podemos hacer es configurar nuestro report server para que se creen más procesos de manera automática si existen reportes en cola d ejecución. La configuración inicial de report server solo permite ejecutar uno a uno las colas de reportes, por lo que puede suceder que esta cola de impresión se demore en atenderse si hablamos de reportes complejos.
Para esto nos podemos ayudar de los parámetros del sistema de reporte

  • Sistemas Iniciales (initEngine)
  • Máximo de Sistemas (maxEngine)  
Sistemas Iniciales (initEngine): Indica el número de procesos iniciales que empezaran atender las peticiones de ejecución de reportes. El valor por defecto es 1.
Máximo de Sistemas (maxEngine): Indica el número de procesos máximo que se pueden crear para atender las peticiones de ejecución de reportes. El valor por defecto es 1.

Lo recomendable es que Máximo de Sistemas (maxEngine) se configure con la cantidad de procesadores que posee el servidor donde reside el servicio de reportes.
Sistemas Iniciales (initEngine) yo recomiendo que se deje su valor en 1, para que luego no queden procesos subutilizado que ocupan memoria. Por qué ? Bueno como les dije este parámetro indica la cantida de procesos iniciales que atenderán las peticiones de impresión, Ejemplo:
Si maxEngine es igual 4 y initEngine es igual a 4 entonces desde que se levanta el servicio de report habrán 4 procesos para impresiones estén o no haciendo solicitudes
Si maxEngine es igual 4 y initEngine es igual a 1 entonces desde que se levanta el servicio de report habrá 1 proceso para impresiones estén o no haciendo solicitudes, y si el proceso esta ocupado se procederá a crearse otro para atender una petición, luego de finalizar este nuevo proceso se eliminará.

 Configuración desde el EM de Oracle:

1-Ingresamos a la url del em y digitamos el usuario y clave.

2-Seleccionamos nuestro componente del sistema Reporte que deseamos configurar

3-Vamos a la parte inferior de Administración y damos click al link configuración.

4-Cambiamos el valor del parámetro (en mi caso tengo 2 procesadores con 4 núcleo y lo configuro con 8) y damos click en aceptar.

 5-Indicamos que si deseamos reiniciar el servicio de reportes.

6-Listo, ya tenemos nuestro servidor de reportes configurado para que pueda atender a 8 solicitudes a la vez.



Configuración desde el archivo:
1-Editamos el archivo de configuración .conf del servidor de reportes ubicado en %OAS_HOME%\reports\conf, el nombre de mi servidor de reportes es srv_reporte01 por lo que el archivo de configuración tendrá el mismo nombre.
2-Buscamos dentro de la sección engine y buscamos los parámetros initEngine y maxEngine. Luego de encontrarlo modificamos sus valores.
<engine id="rwEng" class="oracle.reports.engine.EngineImpl" initEngine="1" maxEngine="8" minEngine="0" engLife="50" maxIdle="30" callbackTimeOut="90000">
<property name="sourceDir" value="E: \Reportes "/>
<!--property name="tempDir" value="your reports temp directory"/-->
<!--property name="keepConnection" value="yes"/-->
</engine>

 3-Bajamos y subimos el servicio del report server, vamos al %OAS_HOME%opmn\bin.    opmnctl stopproc ias-component=srv_reporte01
    opmnctl startproc ias-component=srv_reporte01

 




  1. Listo, ya tenemos configurado nuestro servidor de reportes para que pueda atender 8 solicitudes a la vez

Nota: El cambio de este parámetro involucra reiniciar el servicio de reportes, por lo que se debe de tener en consideración que el servicio estará fuera lo que tarde en reiniciarse.

sábado, 6 de agosto de 2011

Como instalar Oracle Developer Suite 10g en windows vista y windows 7

Funciona el Oracle Developer Suite 10g para vista y W7?

Para los que ya han realizado la instalación saben que no funciona,  no si instalarle un parche necesario.

Por un tiempo tenia que trabajar en mi windows vista con una maquina virtual con XP y ahi trbajar el developer, pero encontré la forma y a continuación se las indicare.
PRE-REQUISITOS
Descarguen los parches de los siguientes links:
Parche 1 -
             Parte 1
                  http://www.megaupload.com/?d=Z7B8941C

             Parte 2
                  http://www.megaupload.com/?d=3JJZT8JK
Parche 2 -
                  http://www.megaupload.com/?d=52528F30

Tambien pueden descargarlo desde la página de Oracle buscando p5983622_10123_WINNT y p7047034_10105_WINNT.

Debe de estar instalado el developer suite 10g previo a la ejecucion de los siguientes paso del parchado.


PASOS A SEGUIR
1.       Antes de ejecutar \Parche 1\p5983622_10123_WINNT\Disk1\Setup.exe primero cambiar para que se ejecute con compatibilidad WX SP2



2.       Ejecutar programa install y dar click en siguiente

3.       Seleccionar la ubicación en donde se encuentra ya instalado el developery damos click en siguiente.
4.       Durante el proceso de instalación saldran dos errores, solo sigan con la instalación y dar aceptar y continuar.


5.       Una vez finalizado copia la carpeta p7047034_10105_WINNT ( que esta dentro de de archivo parche 2) en una ruta mas accesible como en el raiz del c: y luego abrir una ventana de comandos y ejecutar:
REM <<HOME_ORACLE_DEVELOPE>> debe de ser remplazado por la ruta donde tengan instalado el developer.
cd <<HOME_ORACLE_DEVELOPE>>\opatch
set ORACLE_HOME=<<HOME_ORACLE_DEVELOPE>>
opatch lsinventory
REM <<Ruta del parche>> debe de remplazarse por la ruta del parche 2 
REM p7047034_10105_WINNT que copiamos en el c o la ruta donde lo copiaron 
REM que para nuestro ejemplo es c:\p7047034_10105_WINNT\7047034
opatch apply <<Ruta del parche>>

NOTA
Si al arrancar la instalación da un error de que la memoria virtual no es suficiente, se deberá cambiar la configuración del sistema operativo para que no lo asigne de forma automática si no de forma manual.
Esto ya que en XP la memoria virtual era fijada de manera constante y en vista y 7 la memoria es automática y va ajustandose segun las necesidades por lo que cuando arranca el tamaño es bajo.
 En mi caso de le di 1,500 mb de inicial y un maximo de 3,000 mb