lunes, 11 de junio de 2012

ORA-01031: insufficient privileges al ingresar al SQLPLUS

Si al tratar de ingresar al sqlplus como sysdba con el siguiente comando te da un error:
>set ORACLE_SID=D7ITEST 
>sqlplus / as sysdbaSQL*Plus: Release 10.2.0.5.0 - Production on Lun Jun 11 13:27:23 2012
Copyright (c) 1982, 2010, Oracle.  All Rights Reserved.
ERROR:
ORA-01031: insufficient privileges


Este error se presenta cuando el usuario del SO no esta dentro del grupo ORA_DBA del host donde se encuentra instalado la base de dato.

Para que no se presente este error deberas agregar al ususario dentro del grupo ORA_DBA
Luego de que se agregue el usuario de OS al grupo no habrá problema de ingresar.

viernes, 18 de mayo de 2012

Error al crear repositorio del Enterprise Manager 10G con el EMCA

Saludos,

No es raro que la consola del Enterprise Manager falle debido a cambios en el host como el cambio de dominio, cambio de ip o de ip fija a dínamica. Aunque esto falle no es de preocuparnos ya que lo podemos reconstruir sin afectar la operación de la base de datos. Aunque esto ya lo había realizado un monton de veces se presento un error al tratar de generarlo. Mi version de base de datos en la que estoy trabajando es 10.2.0.3.0

Claro que antes de crear el repositorio borre el anterior con el comando:
emca -deconfig dbcontrol db -repos drop

Revisando el log "emca_2012-05-18_09-47-23-AM.log" no me decía mucho acerca del error

May 18, 2012 9:51:36 AM oracle.sysman.emcp.EMReposConfig createRepository
CONFIG: ORA-01403: no data found
ORA-06512: at line 259
oracle.sysman.assistants.util.sqlEngine.SQLFatalErrorException: ORA-01403: no data found
ORA-06512: at line 259
 at oracle.sysman.assistants.util.sqlEngine.SQLEngine.executeImpl(SQLEngine.java:1467)
 at oracle.sysman.assistants.util.sqlEngine.SQLEngine.executeScript(SQLEngine.java:841)
 at oracle.sysman.assistants.util.sqlEngine.SQLPlusEngine.executeScript(SQLPlusEngine.java:265)
 at oracle.sysman.assistants.util.sqlEngine.SQLPlusEngine.executeScript(SQLPlusEngine.java:306)
 at oracle.sysman.emcp.EMReposConfig.createRepository(EMReposConfig.java:389)
 at oracle.sysman.emcp.EMReposConfig.invoke(EMReposConfig.java:191)
 at oracle.sysman.emcp.EMReposConfig.invoke(EMReposConfig.java:133)
 at oracle.sysman.emcp.EMConfig.perform(EMConfig.java:142)
 at oracle.sysman.emcp.EMConfigAssistant.invokeEMCA(EMConfigAssistant.java:485)
 at oracle.sysman.emcp.EMConfigAssistant.performConfiguration(EMConfigAssistant.java:1141)
 at oracle.sysman.emcp.EMConfigAssistant.statusMain(EMConfigAssistant.java:469)
 at oracle.sysman.emcp.EMConfigAssistant.main(EMConfigAssistant.java:418)
May 18, 2012 9:51:36 AM oracle.sysman.emcp.EMReposConfig invoke

Revisando el log del script que ejecutó para ver en donde se dió el error "emca_repos_create_2012-05-18_09-48-37-AM.log" tampoco ayudaba mucho:

PL/SQL procedure successfully completed.
No errors.
BEGIN
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 259

Para determinar el error para ver en donde se caia realice un monitoreo del proceso y econtre que el ORA-01403: no data found se generaba en el script "self_monitor_post_creation.sql" dentro en la ruta %HOME_ORACLE%\db_1\sysman\admin\emdrep\sql\core\latest\self_monitor.

Revisando este archivo se encontró la linea que generaba el error "SELECT host_name into l_host_name FROM v$instance WHERE ROWNUM=1;". Esto sucede ya que en version 10.2.0.3 esto no retorna datos.

Para solucionar este error hay dos opciones:
  1. Parchar a la version 10.2.0.5.0(Version que se presento el error 10.2.0.3.0)
  2. Modificar el script "self_monitor_post_creation.sql" modificando "SELECT host_name into l_host_name FROM v$instance WHERE ROWNUM=1;" por esto "SELECT host_name into l_host_name FROM v$instance WHERE ROWNUM<=1;"
Cualquiera de las dos opciones puedes usar para solucionar el error, pero antes no olvidar borrar el repositorio que quedo a medias.

martes, 24 de enero de 2012

ORACLE ASM

Saludos, este post lo dedicare para explicar de manera breve que es ASM, las ventajas de usar ASM y dar un pequeño ejemplo de la creación de una instancia simple ASM.
 ASM es Administración Automática de Almacenamiento o sus siglas en ingles Automatic Storage Management, es una nueva característica introducida desde la versión 10G cuyo objetivo es simplificar la administración de los archivos de base de datos como datafile, control file, spfile , log file y archive log.



Acerca de ASM (Administración Automática de Almacenamiento)  ASM Esta característica tiene como objetivo simplificar la administración de los archivos relacionados con la base de datos Oracle como: 

  • Database files
  • Control files
  • Online redo log files
  • Archived redo log files
  • Archivo Flash recovery area
  • Archivos RMAN 

Exceptiones:
  • Archivos tracer
  • Archivos log
  • Archivos del sistema operativo

ASM es un file system creado exclusivamente para los archivos de base de datos Oracle, esto permite a los administradores asignar estos archivos a grupos de discos en lugar de discos individuales. ASM nació de la funcionalidad Archivos Administrados por Oracle OMF(Oracle Managed File) que incluye balanceo y redundancia. 
 Esta utilidad ASM es administrada por una instancia Oracle tipo ASM. Esta instancia Oracle ASM no es una versión completa sino que es muy ligera, solo se necesita de estructuras de memoria SGA y procesos background para poder trabajar.
En la imagen anterior se muestra como una base de datos hace uso del repositorio ASM para almacenar los archivos Oracle, además se como interactúa con la instancia ASM. Por debajo vemos las dos unidades de disco que forman un grupo de discos administrado por la instancia Oracle ASM.
Funcionalidades:
  • Simplifica la administración de los archivos Oracle. Debido que a la base ASM se le presenta los grupos de discos para almacenar los archivos, estos por debajo pueden crecer, balancear y administrar de manera independiente y transparente. Por ejemplo, que pasaría si en una base de datos no ASM manejada por archivos del file system del sistema operativo nos estemos quedando sin espacio y nuestra base requiera de mas espacio, bueno, la tarea es agregar discos y agregar datafiles direccionados a las nuevas unidades agregadas, ahora en una base ASM esto es más simple, solo se tiene que agregar los discos al grupo de disco ASM y de forma automática se pondrá a disponibilidad el espacio a los grupos de discos.  


  • Manejo de redundancia dentro de los grupos de discos. Se puede agregar la redundancia para crear espejos de información de tal manera que se evite la perdida de información en caso de que falle uno de los discos.
  • Maneja archivos de gran tamaño.
  • Puede dar servicio a una o más servicios de base de datos residentes en el servidor. Esto quiere decir que solo necesitamos de una sola instancia ASM para brindar servicios a una o mas base de datos que residan en el servidor de la ASM.

  • Creación de una instancia ASM simple de manera manual.
    Como indique, ASM es un file system manjado exclusivamente por Oracle, como lo hace esto? Lo logra por medio de una instancia Oracle tipo ASM quien es el encargado de administrar el file system y proporcionar este servicio a otras bases de datos Oracle para que almacen sus archivos en el repositorio Oracle ASM intance.
    Previo a esto deberá estar instalado Oracle Database 10g o superior para poder realizar la creación de una instancia ASM simple en un sistema operativo windows.
    Nuestro ejercicio constará de:
    • Creación de los directorios
    • Creación de discos ASM con la utilidad ASMTOOL
    • Creación del CSS (Cluster Synchronization Services) requerido para ASM
    • Creación del archivo de parámetros de inicialización ini+ASM.ORA
    • Creación e iniciar la instancia ASM
    Asociar los discos ASM creados a la instancia ASM.El home donde trabajaremos es donde se instaló la base de datos Oracle que para mi caso es C:\Oracle\BDHome_1\10
     
    Creación de los directorios
    Estos directorios son para registrar los archivos log y tracer que se generará la instancia ASM
    C:\>mkdir C:\Oracle\BDHome_1\10\admin\+ASM\bdump
    C:\>mkdir C:\Oracle\BDHome_1\10\admin\+ASM\cdump
    C:\>mkdir C:\Oracle\BDHome_1\10\admin\+ASM\hdump
    C:\>mkdir C:\Oracle\BDHome_1\10\admin\+ASM\pfile
    C:\>mkdir C:\Oracle\BDHome_1\10\admin\+ASM\udump
    Creación de discos ASM con la utilidad ASMTOOL
    Lo ideal es presentar a la instancia ASM dispositivos RAW, pero como es una práctica podemos crear archivos que sirvan a la ASM con la utilidad ASMTOOL es una herramienta que nos permitirá crear en al file sytem unidades ASM para nuestra instancia.
    Esto puede crearse antes o después de crear la instancia ASM. Crear en la carpeta oraasmdisk en la unidad C antes de ejecutar en el cmd los comandos ASMTOOL
    C:\>asmtool -create c:\oraasmdisk\asmdsk01.asm 2048m
    C:\>asmtool -create c:\oraasmdisk\asmdsk02.asm 2028m
    Creación del CSS (Cluster Synchronization Services) requerido para ASM
    C:\>set ORACLE_HOME=C:\Oracle\BDHome_1\10\db_1\BIN
    C:\>localconfig.bat add
    Step 1:  creating new OCR repository
    Successfully accumulated necessary OCR keys.
    Creating OCR keys for user 'victor endara', privgrp ''..
    Operation successful.
    Step 2:  creating new CSS service
    successfully created local CSS service
    successfully added CSS to home

    Creación del archivo de parámetros de inicialización ini+ASM.ORA
    Abrimos un bloc de notas y guardamos la siguiente configuración en la ruta C:\Oracle\BDHome_1\10\db_1\database
    #Se indoca el tipo de instancia ASM
    instance_type=ASM
    #Nombre de la instancia
    DB_UNIQUE_NAME = +ASM
    #Ruta de donde tomara los discos
    ASM_DISKSTRING = 'C:\oraasmdisk\*'
    _ASM_ALLOW_ONLY_RAW_DISKS=FALSE
    remote_login_passwordfile=exclusive
    LARGE_POOL_SIZE = 16M
    #ruta en donde se crearan los tracer y logs
    BACKGROUND_DUMP_DEST ='C:\Oracle\BDHome_1\10\admin\+ASM\bdump'
    USER_DUMP_DEST = 'C:\Oracle\BDHome_1\10\admin\+ASM\udump'
    CORE_DUMP_DEST = 'C:\Oracle\BDHome_1\10\admin\+ASM\cdump'
    #Nombre del grupo de disco a crear
    ASM_DISKGROUPS='dgroup1'

    Crear e iniciar la instancia ASM
    Primero crearemos la instancia ASM indicando que arrancará con el archivo ini+ASM.ORA que creamos en el paso anterior.
    C:\>ORADIM -NEW -ASMSID +ASM -pfile 'C:\Oracle\BDHome_1\10\db_1\database\init+ASM.ora' -SYSPWD oracle -STARTMODE auto
    Instancia creada. 
    • NEW indicamos que agregaremos una nueva instancia
    • ASMSID indicamos el nombre de la instancia ASM
    • PFILE indicamos la ruta del archivo de inicialización con la que arrancará la instancia
    • SYSPWD indicamos la clave para crear el archivo password para ingresar posteriomente
    Una vez creada la instancia la iniciamos
    C:\>set oracle_sid=+ASM
    El error presenta es normal, ya que todavía no hemos presentados los discos al grupo
    C:\>sqlplus sys/oracle as sysdba
    SQL*Plus: Release 10.2.0.1.0 - Production
    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
    Conectado a una instancia inactiva.
    SQL> startup
    Instancia de ASM iniciada
    Total System Global Area   88080384 bytes
    Fixed Size                  1247444 bytes
    Variable Size              61667116 bytes
    ASM Cache                  25165824 bytes
    ORA-15032: no se han realizado todas las modificaciones
    ORA-15063: ASM ha detectado un numero insuficiente de discos para el grupo de
    discos "DGROUP1"

    Asociar los discos ASM creados a la instancia ASM.
    Presentaremos los discos creados al grupo para que puedan ser usados como repositorios.
    SQL> create diskgroup dgroup1 normal redundancy disk
      2  'C:\oraasmdisk\asmdsk01.asm',
      3  'C:\oraasmdisk\asmdsk02.asm';
    Grupo de discos creado.
    SQL> startup force;
    Instancia de ASM iniciada
    Total System Global Area   88080384 bytes
    Fixed Size                  1247444 bytes
    Variable Size              61667116 bytes
    ASM Cache                  25165824 bytes
    Grupos de discos de ASM montados
    Consultemos es espacio disponible para el grupo
    SQL> select name, state, total_mb, free_mb from  V$ASM_DISKGROUP;
    NAME                           STATE         TOTAL_MB    FREE_MB
    ------------------------------ ----------- ---------- ----------
    DGROUP1                        MOUNTED           4076       3974
    Consultemos los discos asociados al grupo
    SQL> SELECT name, path FROM v$asm_disk;
    NAME          PATH
    ------------- ------------------------------------------
    DGROUP1_0000  C:\ORAASMDISK\ASMDSK01.ASM
    DGROUP1_0001  C:\ORAASMDISK\ASMDSK02.ASM

    Listo!!! Ahora ya tenemos nuestra instancia ASM básica disponible para presentarlo como almacenamiento.

    domingo, 15 de enero de 2012

    ORA-01031: insufficient privileges (DBD ERROR: OCISessionBegin)

    Error al ingresar ASMCMD "ORA-01031: insufficient privileges (DBD ERROR: OCISessionBegin)" Este error ocurre cuando no se tiene los privilegios o accesos necesarios a nivel del sistemas operativo.

    Para resolver este problema debes de asegurarte de:

    • Asegurate de que el usuario logoneado en el sistemas operativo tenga asociado el grupo ORA_DBA.
    • Que exista la siguiente configuración en el SQLNET.ORA: SQLNET.AUTHENTICATION_SERVICES = (NTS)

    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.