miércoles, 30 de octubre de 2013

ORA-02396

Se puede poner un límite en el tiempo inactivo y continuo de una sesión de la manera siguiente. Antes de empezar, es necesario cambiar resource_limit a true. Si no se hace esto, los límites no se hacen cumplir: 

SQL> alter system set resource_limit = true
  2  /
 
Sistema modificado.
 
SQL> 

Luego debes crear un perfil con un límite en el tiempo de inactividad que se llama idle_time. El valor que empleas es en minutos: 

SQL> create profile idle_time_profile
  2  limit idle_time 1
  3  /
 
Perfil creado.
 
SQL> 

Entonces necesitas un usuario para probar el perfil. Se puede crearlo así: 

SQL> create user idle_time_user
  2  identified by idle_time_user
  3  profile idle_time_profile
  4  /
 
Usuario creado.
 
SQL> grant create session to idle_time_user
  2  /
 
Concesion terminada correctamente.
 
SQL>
 
Para probar el perfil, el usuario nuevo se conecta a la base de datos. Lo hago en rojo porque desde ahora tendré que trabajar en dos sesiónes distintas: 

SQL> conn idle_time_user/idle_time_user
Conectado.
SQL>
 
Luego el usuario sys se conecta a la base de datos para monitorizar la sesión del usuario idle_time_user. Por eso, lo hago en azul en una sesión distinta. El usuario sys sabe que la sesión de idle_time_user no hace nada porque tiene un status de INACTIVE:
 
SQL> conn / as sysdba
Conectado.
SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>

Después de un minuto de inactividad, Oracle podría cerrar la sesión de idle_time_user pero no suele hacerlo inmediatamente:
 
SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
Tras dos minutos, Oracle todavía no se da cuenta de la inactividad de idle_time_user

SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
INACTIVE
 
SQL> exec dbms_lock.sleep(60);
 
 
Procedimiento PL/SQL terminado correctamente.
 
SQL>
 
Pero tras 3 minutos, Oracle se da cuenta y cambia el status de idle_time_user a SNIPED: 

SQL> select status from v$session
  2  where username = 'IDLE_TIME_USER'
  3  /
 
STATUS
--------
SNIPED
 
SQL>
 
Y cuando idle_time_user vuelve a su sesión, Oracle le da un error ORA-02396 y le dice de conectarse otra vez a la base de datos antes de continuar: 

SQL> select sysdate from dual;
select sysdate from dual
*
ERROR en linea 1:
ORA-02396: ha excedido el tiempo maximo de
inactividad, vuelva a conectarse
 
SQL>

viernes, 18 de octubre de 2013

Como se Puede Emplear un Usuario sin Conocer su Contraseña en Oracle 11


En Oracle versión 11, llegaron contraseñas sensibles al uso de mayúsculas y minúsculas:

SQL> conn / as sysdba
Conectado.
SQL> grant create session to andrew
  2  identified by secret_password
  3  /
 
Concesion terminada correctamente.
 
SQL> conn andrew/secret_password
Conectado.
SQL> conn andrew/SECRET_PASSWORD
ERROR:
ORA-01017: nombre de usuario/contraseña no validos; conexion
denegada
 
Advertencia: !Ya no esta conectado a ORACLE!
SQL> 

Si quieres emplear un usuario en una base de datos sin conocer su contraseña normal, debes mirar su contraseña encriptada de la manera siguiente: 

SQL> conn / as sysdba
Conectado.
SQL> select spare4 from sys.user$
  2  where name = 'ANDREW'
  3  /
 
SPARE4
-----------------------------------------------------------------
S:CD4E8CCD97532CE9EBB35A8D5B910CF9F554711216EFDDECECD32DC4943A
 
SQL> 

Luego se puede cambiar la contraseña normal y emplear el usuario. 

SQL> alter user andrew identified by reid
  2  /
 
Usuario modificado.
 
SQL> conn andrew/reid
Conectado.
SQL> select sysdate from dual
  2  /
 
SYSDATE
---------
18-OCT-13
 
SQL> 

Después de terminar la sesión, debes restaurar la contraseña encriptada: 

SQL> alter user andrew identified by values
  2  'S:CD4E8CCD97532CE9EBB35A8D5B910CF9F554711216EFDDECECD32DC4943A'
  3  /
 
Usuario modificado.
 
SQL> 

Entonces el dueño usual del usuario podrá utilizarlo con la contraseña normal que será todavía sensible al uso de mayúsculas y minúsculas:

SQL> conn andrew/secret_password
Conectado.
SQL> conn andrew/SECRET_PASSWORD
ERROR:
ORA-01017: nombre de usuario/contraseña no validos; conexion
denegada
 
Advertencia: !Ya no esta conectado a ORACLE!
SQL>

domingo, 13 de octubre de 2013

La Columna Table_Lock y el Error ORA-00069

Probé este ejemplo en Oracle 11.2.0.2.7. Un colega quería saber cual era el  propósito de la columna table_lock en la vista dba_tables. Yo no sabía y por lo tanto decidí investigar. Para empezar, miré los valores en la columna table_lock en una base de datos de prueba: 

SQL> select table_lock, count(*)
  2  from dba_tables
  3  group by table_lock
  4  / 

TABLE_LOCK   COUNT(*)
---------- ----------
ENABLED          2760

SQL>

Esto me hizo pensar que el valor predeterminado fuese ENABLED. Para confirmar esta teoría, creé una tabla de prueba: 

SQL> create table andrew (col1 number)
  2  /
 
Tabla creada.
 
SQL>

Como se esperaba, la columna table_lock tenía un valor de ENABLED para esta tabla nueva: 

SQL> l
  1  select table_lock from user_tables
  2* where table_name = 'ANDREW'
SQL> /
 
TABLE_LOCK
----------
ENABLED

SQL>

Se puede cambiar el valor de table_lock de la manera siguiente:

SQL> alter table andrew disable table lock
  2  /
 
Tabla modificada.

SQL>

Tras hacer esto, el valor de table_lock cambia a DISABLED: 

SQL> select table_lock from dba_tables
  2  where table_name = 'ANDREW'
  3  /
 
TABLE_LOCK
----------
DISABLED

SQL>

Luego no es posible tener un bloqueo en la tabla:

SQL> l
  1* lock table andrew in share mode
SQL> /
lock table andrew in share mode
           *
ERROR en linea 1:
ORA-00069: no se puede obtener el bloqueo -- bloqueos
de tabla desactivados para ANDREW

SQL>

Tampoco es posible cambiar la tabla de cualquier manera. Por ejemplo, no se puede renombrarla: 

SQL> rename andrew to fred
  2  /
rename andrew to fred
*
ERROR en linea 1:
ORA-00069: no se puede obtener el bloqueo -- bloqueos
de tabla desactivados para ANDREW
 
SQL>

Si quieres hacer estas cosas, es necesario cambiar table_lock a ENABLED: 

SQL> alter table andrew enable table lock
  2  /
 
Tabla modificada.
 
SQL>

Entonces se puede cambiar la tabla otra vez:

SQL> rename andrew to fred
  2  /
 
Nombre de tabla cambiado.
 
SQL>

Así se puede ver que cuando table_lock sea ENABLED, Oracle te permite tener bloqueos en la tabla y cambiar su definición.

En inglés / in English

jueves, 10 de octubre de 2013

Característica Nueva de Flashback en Oracle 11.2

Hallé esta información aquí. En Oracle 10, era necesario cerrar una base de datos y abrirla con STARTUP MOUNT antes de cambiarla a FLASHBACK ON. En Oracle 11.2, se puede hacerlo en una base de datos abierta. Aquí está un ejemplo, que probé en Oracle 11.2.0.2.7: 

SQL> select open_mode, flashback_on from v$database
  2  /
 
OPEN_MODE            FLASHBACK_ON
-------------------- ------------------
READ WRITE           NO
 
SQL> alter database flashback on
  2  /
 
Base de datos modificada.
 
SQL> select flashback_on from v$database
  2  /
 
FLASHBACK_ON
------------------
YES
 
SQL> alter database flashback off
  2  /
 
Base de datos modificada.
 
SQL> select flashback_on from v$database
  2  /
 
FLASHBACK_ON
------------------
NO
 
SQL>