domingo, 9 de febrero de 2014

Obtener Fechas Pl Sql

  • Primer dia de la semana actual

select TRUNC(SYSDATE, 'Day') Fday from dual;
Ejemplo. 
Si Sysdate = 28/10/2010 Jueves
Resultado:

  • Primer dia de la semana de cualquier fecha

select TRUNC(to_date('31/12/2010','dd/mm/yyyy'), 'Day') FDay from dual;
u obteniendo la fecha desde el sysdate.
La semana anterior
select TRUNC(SYSDATE-7 , 'Day') Fday from dual;
Para la semana siguiente
select TRUNC(SYSDATE+7 , 'Day') Fday from dual;
  • Último dia de la semana
De la semana actual

select TRUNC(SYSDATE, 'Day')+6 Fday from dual;
 Ejemplo
Si el sysdate es 28/10/2010
Resultado:


La semana anterior
select TRUNC(SYSDATE-7 , 'Day')+6 Fday from dual;
La semana siguiente
select TRUNC(SYSDATE+7 , 'Day')+6 Fday from dual;

  • Primer Dia del Mes
El mes Actual
select TRUNC(SYSDATE , 'Month') Fday from dual;
 Ejemplo
Si el sysdate es 28/10/2010
Resultado:


El mes anterior
select TRUNC(TRUNC(SYSDATE , 'Month')-1 , 'Month') Fday from dual;
El siguiente mes
select TRUNC(LAST_DAY(SYSDATE)+1 , 'Month') Fday from dual;


  • Último día del mes
Del mes actual
select TRUNC(LAST_DAY(SYSDATE)) Fday from dual;
 Ejemplo
Si el sysdate es 28/10/2010
Resultado:


El mes anterior
select LAST_DAY(TRUNC(TRUNC(SYSDATE , 'Month')-1 , 'Month')) Fday from dual;
El mes siguiente
select LAST_DAY(TRUNC(LAST_DAY(SYSDATE)+1 , 'Month')) Fday from dual;



  • Primer dia del año
Del presente año
select TRUNC(SYSDATE , 'Year') Fday from dual;
 Ejemplo
Si el sysdate es 28/10/2010
Resultado:


El año anterior
select TRUNC(TRUNC(SYSDATE , 'Year')-1 , 'Year') Fday from dual;
El año siguiente
select ADD_MONTHS(TRUNC(SYSDATE , 'Year'),12) Fday from dual;


  • Último dia del año
Del presente año
select LAST_DAY(ADD_MONTHS(TRUNC(SYSDATE , 'Year'),11)) Fday from dual;
 Ejemplo
Si el sysdate es 28/10/2010
Resultado:

El año anterior
select LAST_DAY(ADD_MONTHS(TRUNC(TRUNC(SYSDATE , 'Year')-1 , 'Year'),11)) from dual;
El año siguiente
select LAST_DAY(ADD_MONTHS(TRUNC(TRUNC(SYSDATE , 'Year')-1 , 'Year'),-13)) from dual;

martes, 14 de enero de 2014

Reusar un Select gracias a la clausula With


La sentencia WITH se añadió a la sintaxis SQL de Oracle en Oracle 9.2. 

La cláusula WITH se puede procesar como una vista en línea, crea una tabla temporal. La ventaja de esto último es que las referencias repetidas a la subconsulta pueden ser más eficientes ya que los datos se recuperan fácilmente de la tabla temporal, en lugar de ser consultados por cada referencia. La variación en el rendimiento puede ser mayor o menor según el caso, pero para simplificar un query que tiene varias subconsultas siempre es muy útil.

En este artículo se muestra cómo la cláusula WITH se puede utilizar para reducir la repetición y simplificar las sentencias SQL complejas. Puede que los ejemplos no sean la mejor manera de hacer esta consulta en particular sirve para poder explicar el uso de la clausula WITH.

WITH AVG_AREA AS(
SELECT AREA,
 AVG(SALARIO) AVG_SALARIO
FROM EMPLEADOS
GROUP BY AREA )

SELECT CEDULA, AREA, SALARIO, AVG_SALARIO, SALARIO-AVG_SALARIO VARIACION
FROM EMPLEADOS M, AVG_AREA A
WHERE M.AREA = A.AREA;


Con el ejemplo podemos apreciar la sintaxis, inicialmente con la clausula with
el subquery que se crea y luego de este el query principal donde se usa el subquery ya renombrado.

Es posible tener varias clausulas With, basta separarlas con comas. Así:

WITH AVG_AREA AS(
SELECT AREA,
 AVG(SALARIO) AVG_SALARIO
FROM EMPLEADOS
GROUP BY AREA ),

AVG_EMPRESA AS(
SELECT AVG(SALARIO) AVG_TOTAL
FROM EMPLEADOS)

SELECT CEDULA, AREA, SALARIO, SALARIO-AVG_SALARIO VARIACION_AREA,
SALARIO-AVG_TOTAL VARIACION_EMPRESA
FROM EMPLEADOS M, AVG_AREA A, AVG_EMPRESA E
WHERE M.AREA = A.AREA;

Es importante anotar que todos las subconsultas que se incluyan en el With
deben usarse en la consulta principal sino nos dará el error 
ORA-01762 View query block not in from

jueves, 2 de enero de 2014

Sesiones Bloqueadas en Oracle



REVISAR SESIONES BLOQUEDAS EN ORACLE

Muchas veces debido a la codificación de nuestras aplicaciones se presentan casos en los que un segundo usuario se queda esperando mucho tiempo a que finalice una transacción porque un primer usuario ya tiene bloqueada una o varias tablas que el segundo requiere.
¿Cómo saber que sesiones están bloqueando y cuales están esperando?

1. Qué usuarios están creando bloqueos?

SELECT Session_Id, Lock_Type, Mode_Held

  FROM Dba_Locks

 WHERE Blocking_Others = 'Blocking';

Con esta sentencia sabré el Id de la sesión que me está ocasionando un bloqueo. Pero quizás quiera saber también quienes están esperando. Los resultado de esta consulta son algo así:
Esto quiere decir que la sesión 171 tiene elementos bloqueados


2. Qué usuarios están esperando a que otra sesion desbloquee recuersos?

SELECT * FROM Dba_Waiters;

Los resultado de esta consulta son como este:
Me muestra que la sesión 69 está esperando a que la 171 libere algún recurso.
Sin embargo estos resultados me dicen poco, tendría que ingresar a ver las sesiones para saber quiénes son estos usuarios y qué están haciendo, pero podemos mejorar el query


3. Qué recursos están usando quienes bloquean y esperan?

SELECT l.Sid, l.Id1, l.Id2, l.Lmode, o.Owner Object_Owner, o.Object_Name,

       s.Username, s.Osuser, s.Machine, s.Wait_Class, s.Seconds_In_Wait

  FROM Sys.All_Objects o, V$lock l, V$session s, Dba_Waiters d

 WHERE (l.Sid = d.Waiting_Session OR l.Sid = d.Holding_Session)

   AND l.Type = 'TM'

   AND o.Object_Id = l.Id1

   AND l.Sid = s.Sid

   ORDER BY l.Id1;

El query nos dará este resultado:
En la columna Object_Name nos dice cual es el recurso usado o esperado, como está ordenado por el número de apariciones en el resultado, podemos saber cuáles son las que están bloqueadas. El OSUSER es el usuario de sistema operativo y Machine el nombre del equipo con el que el usuario se logueó, así podremos identificar mejor a los actores en este asunto. Seconds_in_Wait me dice el tiempo que lleva esperando (el que está en espera) y la última columna es simplemente la cuenta con la que estoy ordenando el resultado.


Una vez finalizada alguna de las dos sesiones en conflicto el resultado de los 3 querys debe estar vacio.

Espero les ayude.