Mostrando entradas con la etiqueta Oracle. Mostrar todas las entradas
Mostrando entradas con la etiqueta Oracle. Mostrar todas las entradas

viernes, 22 de julio de 2016

Aumentar la velocidad de la instrucción DELETE para Oracle

El uso de hints puede ayudarte a aumentar la velocidad de una instrucción. El hint PARALLEL no fuerza la ejecución en paralelo, pero puede modificar el grado de parallelismo de una tabla para que ORACLE use este coste aproximado.


  • Si el tiempo de tardanza se produce durante la búsqueda de candidatos a borrar, entonces puedes usar los siguientes hints para ayudar a agilizar:

Para Full Table Scan

delete /*+ parallel(a,4) full(a) */
from cam_tab_meta a
where db_name like 'cam01'

Para Index Fast Full Scan

delete /*+ parallel_index(a,4) index_ffs(a) */
from cam_tab_meta a
where db_name like 'cam01'


  • Si el tiempo de tardanza pasa en la etapa de eliminar filas, entonces se puede utilizar DML paralelo que se encuentra desactivado por defecto, por lo que se debe primero activar dml:

Enable Parallel dml

alter session enable parallel dml;

delete /*+ parallel(a,4) full(a) */
  from cam_tab_meta a
 where db_name like 'cam01'

miércoles, 24 de junio de 2015

Consultas SQL para la base de datos Oracle

Consultas SQL útiles para obtener información sobre Oracle Database 


Vista que muestra el estado de la base de datos:
select * from v$instance

Consulta que muestra si la base de datos está abierta:
select status from v$instance

Vista que muestra los parámetros generales de Oracle:
select * from v$system_parameter

Versión de Oracle:
select value 
from v$system_parameter 
where name = 'compatible'

Ubicación y nombre del fichero spfile:
select value 
from v$system_parameter 
where name = 'spfile'

Ubicación y número de ficheros de control:
select value 
from v$system_parameter 
where name = 'control_files'

Nombre de la base de datos
select value 
from v$system_parameter 
where name = 'db_name'

Vista que muestra las conexiones actuales a Oracle:
select osuser, username, machine, program 
  from v$session 
  order by osuser

Vista que muestra el número de conexiones actuales a Oracle agrupado por aplicación que realiza la conexión
select program Aplicacion, count(program) Numero_Sesiones
from v$session
group by program 
order by Numero_Sesiones desc

Vista que muestra los usuarios de Oracle conectados y el número de sesiones por usuario

select username Usuario_Oracle, count(username) Numero_Sesiones
from v$session
group by username
order by Numero_Sesiones desc

Propietarios de objetos y número de objetos por propietario
select owner, count(owner) Numero 
  from dba_objects 
  group by owner 
  order by Numero desc

Diccionario de datos (incluye todas las vistas y tablas de la Base de Datos):
select * from dictionary

select table_name from dictionary

Muestra los datos de una tabla especificada (en este caso todas las tablas que lleven la cadena "EMPLO"):
select * 
from ALL_ALL_TABLES 
where upper(table_name) like '%EMPLO%'

Muestra los disparadores (triggers) de la base de datos Oracle Database:
 select *
from ALL_TRIGGERS 

Tablas propiedad del usuario actual:
select * from user_tables

Todos los objetos propiedad del usuario conectado a Oracle:
select * from user_catalog


Consulta SQL para el DBA de Oracle que muestra los tablespaces, el espacio utilizado, el espacio libre y los ficheros de datos de los mismos:
Select t.tablespace_name  "Tablespace",  t.status "Estado",  
    ROUND(MAX(d.bytes)/1024/1024,2) "MB Tamaño",
    ROUND((MAX(d.bytes)/1024/1024) - 
    (SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024),2) "MB Usados",   
    ROUND(SUM(decode(f.bytes, NULL,0, f.bytes))/1024/1024,2) "MB Libres", 
    t.pct_increase "% incremento", 
    SUBSTR(d.file_name,1,80) "Fichero de datos"  
FROM DBA_FREE_SPACE f, DBA_DATA_FILES d,  DBA_TABLESPACES t  
WHERE t.tablespace_name = d.tablespace_name  AND 
    f.tablespace_name(+) = d.tablespace_name    
    AND f.file_id(+) = d.file_id GROUP BY t.tablespace_name,   
    d.file_name,   t.pct_increase, t.status ORDER BY 1,3 DESC

Productos Oracle instalados y la versión:
select * from product_component_version

Roles y privilegios por roles:
select * from role_sys_privs

Reglas de integridad y columna a la que afectan:
select constraint_name, column_name 
from sys.all_cons_columns

Tablas de las que es propietario un usuario, en este caso "HR":
SELECT table_owner, table_name 
from sys.all_synonyms 
where table_owner like 'HR'

Otra forma más efectiva (tablas de las que es propietario un usuario):
SELECT DISTINCT TABLE_NAME 
FROM ALL_ALL_TABLES 
WHERE OWNER LIKE 'HR' 
Parámetros de Oracle, valor actual y su descripción:
SELECT v.name, v.value value, decode(ISSYS_MODIFIABLE, 'DEFERRED', 
     'TRUE', 'FALSE') ISSYS_MODIFIABLE,  decode(v.isDefault, 'TRUE', 'YES',
     'FALSE', 'NO') "DEFAULT",  DECODE(ISSES_MODIFIABLE,  'IMMEDIATE',  
     'YES','FALSE',  'NO',  'DEFERRED', 'NO', 'YES') SES_MODIFIABLE,   
     DECODE(ISSYS_MODIFIABLE, 'IMMEDIATE', 'YES',  'FALSE', 'NO',  
     'DEFERRED', 'YES','YES') SYS_MODIFIABLE ,  v.description  
FROM V$PARAMETER v 
WHERE name not like 'nls%'   ORDER BY 1

Usuarios de Oracle y todos sus datos (fecha de creación, estado, id, nombre, tablespace temporal,...):
Select  * FROM dba_users
Tablespaces y propietarios de los mismos:
select owner, decode(partition_name, null, segment_name, 
   segment_name || ':' || partition_name) name, 
   segment_type, tablespace_name,bytes,initial_extent, 
   next_extent, PCT_INCREASE, extents, max_extents 
from dba_segments 
Where 1=1 And extents > 1 order by 9 desc, 3 

Últimas consultas SQL ejecutadas en Oracle y usuario que las ejecutó:
select distinct vs.sql_text, vs.sharable_mem, 
  vs.persistent_mem, vs.runtime_mem,  vs.sorts,
  vs.executions, vs.parse_calls, vs.module,  
  vs.buffer_gets, vs.disk_reads, vs.version_count, 
  vs.users_opening, vs.loads,  
  to_char(to_date(vs.first_load_time,
  'YYYY-MM-DD/HH24:MI:SS'),'MM/DD  HH24:MI:SS') first_load_time,  
  rawtohex(vs.address) address, vs.hash_value hash_value , 
  rows_processed  , vs.command_type, vs.parsing_user_id  , 
  OPTIMIZER_MODE  , au.USERNAME parseuser  
from v$sqlarea vs , all_users au   
where (parsing_user_id != 0)  AND 
(au.user_id(+)=vs.parsing_user_id)  
and (executions >= 1) order by   buffer_gets/executions desc 

Todos los ficheros de datos y su ubicación:
select * from V$DATAFILE

Ficheros temporales:
select * from V$TEMPFILE

Tablespaces:
select * from V$TABLESPACE

Otras vistas muy interesantes:
select * from V$BACKUP

select * from V$ARCHIVE   

select * from V$LOG   

select * from V$LOGFILE    

select * from V$LOGHIST          

select * from V$ARCHIVED_LOG    

select * from V$DATABASE


Memoria Share_Pool libre y usada:
select name,to_number(value) bytes 
from v$parameter where name ='shared_pool_size'
union all
select name,bytes 
from v$sgastat where pool = 'shared pool' and name = 'free memory'

Cursores abiertos por usuario:
select b.sid, a.username, b.value Cursores_Abiertos
      from v$session a,
           v$sesstat b,
           v$statname c
      where c.name in ('opened cursors current')
      and   b.statistic# = c.statistic#
      and   a.sid = b.sid 
      and   a.username is not null
      and   b.value >0
      order by 3

Aciertos de la caché (no debe superar el 1 por ciento):
select sum(pins) Ejecuciones, sum(reloads) Fallos_cache,
  trunc(sum(reloads)/sum(pins)*100,2) Porcentaje_aciertos 
from v$librarycache
where namespace in ('TABLE/PROCEDURE','SQL AREA','BODY','TRIGGER');

Sentencias SQL completas ejecutadas con un texto determinado en el SQL:
SELECT c.sid, d.piece, c.serial#, c.username, d.sql_text 
FROM v$session c, v$sqltext d 
WHERE  c.sql_hash_value = d.hash_value 
  and upper(d.sql_text) like '%WHERE CAMPO LIKE%'
ORDER BY c.sid, d.piece

Una sentencia SQL concreta (filtrado por sid):
SELECT c.sid, d.piece, c.serial#, c.username, d.sql_text 
FROM v$session c, v$sqltext d 
WHERE  c.sql_hash_value = d.hash_value and sid = 105
ORDER BY c.sid, d.piece

Tamaño ocupado por la base de datos
select sum(BYTES)/1024/1024 MB 
from DBA_EXTENTS  

Tamaño de los ficheros de datos de la base de datos:
select sum(bytes)/1024/1024 MB 
from dba_data_files

Tamaño ocupado por una tabla concreta sin incluir los índices de la misma
select sum(bytes)/1024/1024 MB 
from user_segments
where segment_type='TABLE' and segment_name='NOMBRETABLA'

Tamaño ocupado por una tabla concreta incluyendo los índices de la misma
select sum(bytes)/1024/1024 Table_Allocation_MB 
from user_segments
where segment_type in ('TABLE','INDEX') and
  (segment_name='NOMBRETABLA' or segment_name in
    (select index_name 
     from user_indexes 
     where table_name='NOMBRETABLA'))

Tamaño ocupado por una columna de una tabla:
select sum(vsize('NOMBRECOLUMNA'))/1024/1024 MB 
from NOMBRETABLA

Espacio ocupado por usuario:
SELECT owner, SUM(BYTES)/1024/1024 
FROM DBA_EXTENTS MB
GROUP BY owner

Espacio ocupado por los diferentes segmentos (tablas, índices, undo, rollback, cluster, ...):
SELECT SEGMENT_TYPE, SUM(BYTES)/1024/1024 
FROM DBA_EXTENTS MB
GROUP BY SEGMENT_TYPE

Espacio ocupado por todos los objetos de la base de datos, muestra los objetos que más ocupan primero:
SELECT SEGMENT_NAME, SUM(BYTES)/1024/1024 
FROM DBA_EXTENTS MB
GROUP BY SEGMENT_NAME
ORDER BY 2 DESC

Obtener todas las funciones de Oracle: NVL, ABS, LTRIM, ...:
SELECT distinct object_name 
FROM all_arguments 
WHERE package_name = 'STANDARD'
order by object_name

Obtener los roles existentes en Oracle Database:
select * from DBA_ROLES

Obtener los privilegios otorgados a un rol de Oracle:
select privilege 
from dba_sys_privs 
where grantee = 'NOMBRE_ROL'

Obtener la IP del servidor de la base de datos Oracle Database:
select utl_inaddr.get_host_address IP
from dual 

Mostrar datos de auditoría de la base de datos Oracle (inicio y desconexión de sesiones):
select username, action_name, priv_used, returncode
from dba_audit_trail

Comprobar si la auditoría de la base de datos Oracle está activada:
select name, value
from v$parameter
where name like 'audit_trail'

Desbloquear un usuario:
 alter user username account UNLOCK;

lunes, 18 de mayo de 2015

Error: TNS:listener: all appropriate instances are blocking new connections

Solventando el error: TNS:listener: all appropriate instances are blocking new connections

En cuanto a ORACLE, seria importante hacerse las siguiente preguntas:

¿Cómo saber si una base de datos Oracle, esta activa?

SELECT open_mode 
FROM   v$database; 

Si el valor es:

  • 'MOUNTED', la base de datos esta montada 
  • 'READ WRITE', entonces asumimos que la base de datos esta activa 
  • 'READ ONLY' , entonces podría ejecutar consultas en modo de sólo lectura, pero no esta activa.
SELECT controlfile_type 
FROM   v$database; 


Si el valor es:

  • 'CURRENT', la base de datos esta activa
  • 'STANDBY', la base de datos esta en espera.


La siguiente consulta muestra el estado de la instancia, su nombre y su estado.

SELECT instance_name,database_status,status,instance_role,active_state 
FROM   v$instance; 

Si el valor STATUS es: 
  • STARTED, indica que la base de datos esta activa pero no montada
  • MOUNTED, indica que la base de datos esta montada.
  • OPEN, indica que el esta abierta y activa
  • OPEN-MIGRATE, indica que esta en actualización

Si el valor DATABASE_STATUS es: 
  • ACTIVE
Si el valor ACTIVE_STATE es: 
  • 'NORMAL' indica la base de datos está en un estado normal.
  • 'QUIESCING' indica que la sentencia ALTER SYSTEM QUIESCE RESTRICTED ha sido ejecutada: no hay nuevas transacciones de usuario, consultas o  PL/SQL son procesados en este caso. 
  • 'QUIESCED', es Inmovilizado. indica que la sentencia RESTRINGIDO ALTER SISTEMA QUIESCE se ha ejecutado: Transacciones de usuario, consultas o declaraciones PL / SQL emitidas después de la instrucción no se procesan.
¿Verificamos las sessiones? Posiblemente existan mas que la licencia permitida

SELECT Nvl(s.username, '(oracle)') AS username,s.osuser,s.sid,s.serial#,p.spid, 
       s.lockwait,s.status,s.MODULE,s.machine,s.program, 
       To_char(s.logon_time, 'DD-MON-YYYY HH24:MI:SS') AS logon_time 
FROM   v$session s,v$process p 
WHERE  s.paddr = p.addr 
       AND s.username = 'PED_CDD' -- Change the username
ORDER  BY s.username,s.osuser; 


¿Cuantos cursores están permitidos y cuantos se abrieron?

SELECT Max(a.value) AS highest_open_cur,p.value AS max_open_cur 
FROM   v$sesstat a,v$statname b,v$parameter p 
WHERE  a.statistic# = b.statistic# 
       AND b.name = 'opened cursors current' 
       AND p.name = 'open_cursors' 
GROUP  BY p.value; 

¿Cuantos procesos, sessiones y que ultima sql ejecutaron ?

SELECT sess.process,sess.status,sess.username,sess.schemaname,SQL.sql_text 
FROM   v$session sess,v$sql SQL 
WHERE  SQL.sql_id(+) = sess.sql_id; 

SELECT sess.process,sess.status,sess.username,sess.schemaname,SQL.sql_text 
FROM   v$session sess,v$sql SQL 
WHERE  SQL.sql_id(+) = sess.sql_id 
       AND sess.TYPE = 'USER' 

SELECT S.username,s.sid,s.osuser,t.sql_id,sql_text 
FROM   v$sqltext_with_newlines t,v$session s 
WHERE  t.address = s.sql_address 
       AND t.hash_value = s.sql_hash_value 
       AND s.status = 'ACTIVE' 
       AND s.username <> 'SYSTEM' 
ORDER  BY s.sid,t.piece 

Solucion final:

Shutdown Inmediate and Start mount.  LSNRCTL for a STOP and START


viernes, 7 de noviembre de 2014

Cómo solucionar el Error SQL: ORA-02292: restricción de integridad


Si alguna vez intentando borrar un registro de una base de datos Oracle y recibes el siguiente error:

Informe de error:
Error SQL: ORA-02292: restricción de integridad (USUARIO_DB.FK_MAN) violada - registro secundario encontrado
02292. 00000 - "integrity constraint (%s.%s) violated - child record found"
*Cause:    attempted to delete a parent key value that had a foreign
           dependency.
*Action:   delete dependencies first then parent or disable constraint.


La solución pasa por encontrar el registro hijo. Para ello puedes lanzar la siguiente consulta:

SELECT OWNER,
       CONSTRAINT_NAME,
       constraint_type,
       TABLE_NAME,
       r_owner,
       r_constraint_name
FROM all_constraints
WHERE OWNER='USUARIO_DB'
AND CONSTRAINT_NAME='FK_MAN';

Con esta consulta sabrás que tabla esta involucrada. Pero para poder saber que columnas son las que se encuentran involucradas, usa la siguiente consulta: 


SELECT ac.owner AS left_owner,
       ac.constraint_name AS left_name,
       ac.table_name AS left_table,
       acc.column_name AS left_column,
       acc.position AS left_position,
       acr.owner AS right_owner,
       acr.constraint_name AS right_name,
       acr.table_name AS right_table,
       accr.column_name AS right_column,
       accr.position AS right_position
FROM all_constraints ac
JOIN all_cons_columns acc ON ac.constraint_name=acc.constraint_name
JOIN all_constraints acr ON ac.r_constraint_name=acr.constraint_name
JOIN all_cons_columns accr ON acr.constraint_name=accr.constraint_name
WHERE ac.owner='USUARIO_DB'  AND ac.constraint_name='FK_MAN';

Ahora ya tienes la información para borrar el contenido de la tabla relacionada:
 "LEFT_TABLE" y LEFT_COLUMN

Ejecuta la sentencia Delete de la relación:

DELETE
FROM LEFT_TABLE
WHERE LEFT_COLUMN= 'ID_RELACIONADO';

Ahora ya puedes borrar el registro de la tabla principal



miércoles, 17 de septiembre de 2014

Cómo detectar bloqueos en Oracle

Uno de los errores comunes que ocurren en cualquier sistema informático es el bloqueo de tablas. Si has trabajado con Java y algún framework (PDA, Hibernate, iBatis ) seguramente te has encontrado con un error típico:

  • org.hibernate.exception.GenericJDBCException: Could not open connection
  • SQLException: Connections could not be acquired from the underlying database!
  • om.mchange.v2.async.ThreadPoolAsynchronousRunner$DeadlockDetector@4f8244b -- APPARENT DEADLOCK!!! Creating emergency threads for unassigned pending tasks!

Posiblemente haya ocurrido un Deadlock. Si tenemos acceso, con privilegios de administrador, a la base de datos podemos revisar los logs y detectar el error.

¿Qué es un Deadlock? 

Un Deadlock es cuando un mínimo de 2 usuarios se quedan esperando algún dato que está siendo bloqueado por alguna otra sesión. Si ésto sucede, los usuarios involucrados en el Deadlock deben esperar y no pueden continuar con el procesamiento.

En mi caso, hablaremos de detectar bloqueos en la base de datos de Oracle.

Detectar el bloqueo en Oracle

Cuando Oracle detecta que se produjo un Deadlock, lo que hace es parar la ejecución del procedimiento y mostrar el siguiente mensaje de error: ORA-00060: deadlock detected while waiting for resource. Cuando se produce un error como este, Oracle genera un archivo de trace en el directorio UDUMP con información acerca del error.

En Oracle hay una vista v$lock que indica los objetos que se encuentran en bloqueo, el identificador de usuario, sesion y el tipo de bloqueo. Si realizamos un join con la tabla dba_objects podemos obtener el nombre y tipo de los objetos bloqueados:

SELECT
  decode(L.TYPE,'TM','TABLE','TX','Record(s)') TYPE_LOCK,
  decode(L.REQUEST,0,'NO','YES') WAIT,
  S.OSUSER OSUSER_LOCKER,
  S.PROCESS PROCESS_LOCKER,
  S.USERNAME DBUSER_LOCKER,
  O.OBJECT_NAME OBJECT_NAME,
  O.OBJECT_TYPE OBJECT_TYPE,
  concat(' ',s.PROGRAM) PROGRAM,
  O.OWNER OWNER
FROM v$lock l,dba_objects o,v$session s
WHERE 
  l.ID1 = o.OBJECT_ID
  AND s.SID =l.SID
  AND l.TYPE in ('TM','TX');

Los dos tipos de bloqueos:
  • (TM) bloqueos de tablas
  • (TX) bloqueos a nivel de fila

Bloqueos de tablas

Los bloqueos a nivel de tabla son creados cuando se ejecuta una sentencia DML del tipo: update, insert, delete, select ..for update sobre la tabla entera.

Un ejemplo de sentencias DML:

DELETE from mitabla;

UPDATE mitabla SET campo1 = valor;

Bloqueos a nivel de fila

Los bloqueos a nivel de fila se crean cuando se ejecutan sentencias DML contra un conjunto de registros específicos. La siguiente consulta nos permite rápidamente saber que procesos están bloqueados. Si ademas hacemos un join con v$open_cursor podemos ver que consulta es la que se encuentra parada a la espera de que se produzca el desbloqueo para poder ejecutarse.

En la consulta siguiente podemos ver las sentencias paradas y el id de proceso que las esta bloqueando.

-- Esta query permite ver los objetos que estan esperando 
-- a que termine un bloqueo y la sentencia que quieren ejecutar. 
-- el id de proceso nos da la pista de quien esta bloqueando.

select /*+ ordered
no_merge(L_WAITER)
no_merge(L_LOCKER) use_hash(L_LOCKER)
no_merge(S_WAITER) use_hash(S_WAITER)
no_merge(S_LOCKER) use_hash(S_LOCKER)
use_nl(O)
use_nl(U)
*/
/* first the table-level locks (TM) and mixed TM/TX TX/TM */
S_LOCKER.OSUSER OS_LOCKER,
S_LOCKER.USERNAME LOCKER_SCHEMA,
S_LOCKER.PROCESS LOCKER_PID,
S_WAITER.OSUSER OS_WAITER,
S_WAITER.USERNAME WAITER_SCHEMA,
S_WAITER.PROCESS WAITER_PID,
'Table lock (TM): '||U.NAME||'.'||O.NAME||
' - Mode held: '||
decode(L_LOCKER.LMODE,
0, 'None', /* same as Monitor */
1, 'Null', /* N */
2, 'Row-S (SS)', /* L */
3, 'Row-X (SX)', /* R */
4, 'Share', /* S */
5, 'S/Row-X (SSX)', /* C */
6, 'Exclusive', /* X */
'???: '||to_char(L_LOCKER.LMODE))||
' / Mode requested: '||
decode(L_WAITER.REQUEST,
0, 'None', /* same as Monitor */
1, 'Null', /* N */
2, 'Row-S (SS)', /* L */
3, 'Row-X (SX)', /* R */
4, 'Share', /* S */
5, 'S/Row-X (SSX)', /* C */
6, 'Exclusive', /* X */
'???: '||to_char(L_WAITER.REQUEST))
SQL_TEXT_WAITER
from
V$LOCK L_WAITER,
V$LOCK L_LOCKER,
V$SESSION S_WAITER,
V$SESSION S_LOCKER,
sys.OBJ$ O,
sys.USER$ U
where S_WAITER.SID = L_WAITER.SID
and L_WAITER.TYPE IN ('TM')
and S_LOCKER.sid = L_LOCKER.sid
and L_LOCKER.ID1 = L_WAITER.ID1
and L_WAITER.REQUEST > 0
and L_LOCKER.LMODE > 0
and L_WAITER.ADDR != L_LOCKER.ADDR
and L_WAITER.ID1 = O.OBJ#
and U.USER# = O.OWNER#
union
select /*+ ordered
no_merge(L_WAITER)
no_merge(L_LOCKER) use_hash(L_LOCKER)
no_merge(S_WAITER) use_hash(S_WAITER)
no_merge(S_LOCKER) use_hash(S_LOCKER)
no_merge(L1_WAITER) use_hash(L1_WAITER)
no_merge(O) use_hash(O)
*/
/* now the (usual) row-locks TX */
S_LOCKER.OSUSER OS_LOCKER,
S_LOCKER.USERNAME LOCKER_SCHEMA,
S_LOCKER.PROCESS LOCK_PID,
S_WAITER.OSUSER OS_WAITER,
S_WAITER.USERNAME WAITER_SCHEMA,
S_WAITER.PROCESS WAITER_PID,
'TX: '||O.SQL_TEXT SQL_TEXT_WAITER
from
V$LOCK L_WAITER,
V$LOCK L_LOCKER,
V$SESSION S_WAITER,
V$SESSION S_LOCKER,
V$_LOCK L1_WAITER,
V$OPEN_CURSOR O
where S_WAITER.SID = L_WAITER.SID
and L_WAITER.TYPE IN ('TX')
and S_LOCKER.sid = L_LOCKER.sid
and L_LOCKER.ID1 = L_WAITER.ID1
and L_WAITER.REQUEST > 0
and L_LOCKER.LMODE > 0
and L_WAITER.ADDR != L_LOCKER.ADDR
and L1_WAITER.LADDR = L_WAITER.ADDR
and L1_WAITER.KADDR = L_WAITER.KADDR
and L1_WAITER.SADDR = O.SADDR
and O.HASH_VALUE = S_WAITER.SQL_HASH_VALUE

Ejemplo  

En este ejemplo tenemos la tabla SMT_TESTCASE bloqueada con una sentencia:
SELECT * FROM SMT_TESTCASE FOR UPDATE
(En esta sentencia no se ha realizado el commit), así que cualquier sentencia posterior que intente acceder a la tabla se queda en espera (En este caso se paran las dos sentencias DELETE FROM hasta que la tabla bloqueada ya no este en situación de bloqueo).

Usando la consulta de detección de bloqueos
Usando la consulta de filas bloqueadas
Esta última consulta es muy útil porque podemos anotar el "id del proceso bloqueante" y ejecutando la primera consulta con el id de proceso averiguar que objeto (SMT_TESTCASE) y que tipo se encuentra bloqueado (TABLE).

Se debe tener en cuenta que muchas situaciones de bloqueo se producen porque podemos tener el cliente (por ejemplo el Toad) sin activar la opción de “autocommit”.  Así, que al salir del cliente es cuando se nos indica que realicemos el “commit” o “rollback”.  Pero, si ejecutamos una sentencia DDL sin hacer un “commit”, a continuación podemos provocar una situación de bloqueo a otro proceso que intente actualizar la tabla o filas bloqueadas.

Fuentes de ayuda