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

martes, 15 de septiembre de 2015

JOINS - Consultas combinadas


Las consultas  combinadas o JOINS son el resultado de una operación de combinación realizada sobre dos o más tablas. Se pueden realizar las siguientes combinaciones:

Combinación interna (Inner Join)
La combinación interna nos permite mostrar los datos de dos o más tablas a través de una condición WHERE. Para realizar la consulta combinada entre dos tablas debemos escribir una consulta SELECT  en cuya clausula FROM escribiremos el nombre de las dos tablas, separados por comas, y una condición WHERE que obligue mediante un código clave la unión de datos en dos o mas tablas de la siguiente manera:

SELECT RCTA.TRX_NUMBER,
       RCTA.COMMENTS,
       RCTA.INVOICE_CURRENCY_CODE,,
       XDT.CODE,
       XDT.DETAIL_NAME
  FROM APPS.RA_CUSTOMER_TRX_ALL RCTA
 WHERE APPS.XX_DETAIL_TRX_ALL XDT
   AND RCTA.CUSTOMER_TRX_ID = XDT.CUSTOMER_TRX_ID 

Otra opción es utilizar la cláusula INNER JOIN. Su sintaxis es idéntica a la de una consulta SELECT, con la particularidad de que en la clausula FROM sólo aparece con una tabla o vista, añadiéndose el resto de tablas a través de cláusulas INNER JOIN de la siguiente manera:

SELECT RCTA.TRX_NUMBER,
       RCTA.COMMENTS,
       RCTA.INVOICE_CURRENCY_CODE,,
       XDT.CODE,
       XDT.DETAIL_NAME
  FROM APPS.RA_CUSTOMER_TRX_ALL RCTA
 INNER JOIN APPS.XX_DETAIL_TRX_ALL XDT

    ON RCTA.CUSTOMER_TRX_ID = XDT.CUSTOMER_TRX_ID

La cláusula INNER JOIN permite separar completamente las condiciones de combinación con otros criterios, cuando tenemos consultas que combinan nueve o diez tablas esto realmente se agradece. Sin embargo muchos programadores no son amigos de la cláusula INNER JOIN, la razón es que uno de los principales gestores de bases de datos, ORACLE, no la soportaba. Si nuestro programa debía trabajar sobre bases de datos ORACLE no podíamos utilizar INNER JOIN. A partir de la version ORACLE 9i oracle soporta la cláusula INNER JOIN.

Combinación externa Completa (Full Outer Join)
La cláusula FULL OUTER JOIN específica que se debería incluir en el resultado las filas que no cumplen con la condición ON, así como las filas que que cumplen la condición ON. En el campo donde no es coincidente la condición se coloca NULL.

SELECT RCTA.TRX_NUMBER,
       RCTA.COMMENTS,
       RCTA.INVOICE_CURRENCY_CODE,,
       XDT.CODE,
       XDT.DETAIL_NAME
  FROM APPS.RA_CUSTOMER_TRX_ALL RCTA
  FULL OUTER JOIN APPS.XX_DETAIL_TRX_ALL XDT
    ON RCTA.CUSTOMER_TRX_ID = XDT.CUSTOMER_TRX_ID

Combinación externa por la izquierda (Left Outer Join)
La combinación externa con LEFT  OUTER JOIN obtenemos todos los registros de en la tabla que situemos a la izquierda de la clausula JOIN. Devuelve las filas coincidentes más todas las filas de la tabla que se especifican a la izquierda de la palabra clave JOIN.

SELECT RCTA.TRX_NUMBER,
       RCTA.COMMENTS,
       RCTA.INVOICE_CURRENCY_CODE,,
       XDT.CODE,
       XDT.DETAIL_NAME
  FROM APPS.RA_CUSTOMER_TRX_ALL RCTA
  LEFT OUTER JOIN APPS.XX_DETAIL_TRX_ALL XDT
    ON RCTA.CUSTOMER_TRX_ID = XDT.CUSTOMER_TRX_ID


Combinación externa por la derecha (Right Outer Join)

Es lo contrario a Left Outer. La combinación con  RIGHT OUTER JOIN obtenemos el efecto contrario. Devuelve las filas coincidentes más todas las filas de la tabla que se especifican a la derecha de la palabra clave JOIN.

SELECT RCTA.TRX_NUMBER,
       RCTA.COMMENTS,
       RCTA.INVOICE_CURRENCY_CODE,,
       XDT.CODE,
       XDT.DETAIL_NAME
  FROM APPS.RA_CUSTOMER_TRX_ALL RCTA
  RIGHT OUTER JOIN APPS.XX_DETAIL_TRX_ALL XDT
    ON RCTA.CUSTOMER_TRX_ID = XDT.CUSTOMER_TRX_ID

lunes, 10 de noviembre de 2014

Tablas Externas



Las tablas externas es una funcionalidad, que proporciona Oracle, para facilitar la lectura de ficheros formateados, como si fueran tablas. Este tipo de tablas son de sólo lectura y no permite utilizar manipulación de datos (DML). No admite la creación de índices sobre este tipo de tablas. Las tablas externas se utilizan en cargas de ficheros repetitivos y sin tener que acceder al sistema operativo, para realizar la carga.

Para utilizar las tablas externas debe tener un poco de conocimiento del formato de archivo y registro de los ficheros de datos de la plataforma  ORACLE_LOADER  y los archivos de datos en un formato de texto. También debe saber lo suficiente acerca de SQL para poder crear una tabla externa y realizar consultas en contra de ella.

Cuando se crean tablas externas podemos encontrarlos en las siguientes tablas:

dba_external_tables
all_external_tables
user_external_tables


Creación de Tablas Externas
La sintaxis de creación es como la de una tabla estandar de Oracle “CREATE TABLE“, solo que se añade la clausula “ORGANIZATION EXTERNAL” y otros parámetros, que se definen con “ACCESS PARAMETERS“, para definir donde están los datos y como se acceden a ellos.

Para poder acceder al fichero desde Oracle lo primero que definimos, es un objeto directorio de la siguiente manera

CREATE OR REPLACE DIRECTORY dir_externo AS  '/tmp/EXDATA';

Dejamos un archivo en la ruta bajo el nombre de text.txt el cual tiene lo siguiente:

10,Roy Damasco,"16/12/2004"
20,Gladys Daviña,"25/02/2005"
30,Leo Sigil,"04/03/2004"

Se crea la tabla Externa bajo el siguiente script:

CREATE TABLE XX_EMPLOYEES_ALL(
  Codigo NUMBER(4),
  Empleado CHAR(50),
  Fecha_inicio  CHAR(10))
ORGANIZATION EXTERNAL(
  TYPE ORACLE_LOADER DEFAULT DIRECTORY dir_externo
  ACCESS PARAMETERS
  (RECORDS DELIMITED BY NEWLINE
   SKIP 0  
   BADFILE '%a_%p.bad'
   LOGFILE '%a_%p.log'
   FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'  LRTRIM
   MISSING FIELD VALUES ARE NULL
   REJECT ROWS WITH ALL NULL FIELDS
    (Codigo INTEGER EXTERNAL (4),
     Empleado CHAR(50),
     Fecha_inicio CHAR(10) DATE_FORMAT DATE MASK "dd/mm/yyyy"))
   LOCATION ('test.txt')

REJECT LIMIT 0;  

Al consultar la tabla, encontraremos los datos ya ingresados. Cada vez que el archivo se actualiza la tabla externa se llena con los nuevos datos.

Elementos:
SKIP: indica el número de filas a saltarse, para evitar por ejemplo cabeceras. No se puede utilizar con la clausula de paralelización
LRTRIM: Elimina los espacios en blanco
READSIZE: Indica el buffer de lectura. Se indica en número de bytes.
LOGFILE: Contiene los mensajes generados durante el acceso a los datos.
BADFILE: Registros erroneos. Pueden ser por ejemplo por haber caracteres en un campo númerico.
SEQUENCE: las secuencias de registros desechados por las clausulas WHEN no consumen números de la secuencia.
DEFAULT DIRECTORY- especifica la ubicación predeterminada de los archivos que se leen o se escriben por tablas externas. Se especifica la ubicación de un  directorio.
ACCESS PARAMETERS - describen el origen de datos externos e implementa el tipo de tabla externa que se ha especificado. 
LOCATION - Especifica la ubicación de los datos externos. 

viernes, 12 de septiembre de 2014

Error ORA-00060: deadlock detected while waiting for resource

APP-SQLAP-10916: appbdn/1:ORA-00060: deadlock detected while waiting for resource

Este error se origina  Cuando Oracle detecta que se produjo un Deadlock en la base de Datos, lo que hace es cortar la ejecución del proceso y mostrar el siguiente mensaje de error: ORA-00060: deadlock detected while waiting for resource. 

Deadlock
Un Deadlock (abrazo mortal) es cuando 2 o más usuarios están esperando algún dato que está siendo ejecutado por alguna sesión. Si ésto sucede, los usuarios involucrados en el Deadlock deben esperar y no pueden continuar con el procesamiento.

Estos Deadlocks  pueden ocurrir en diferentes escenarios: Pueden ocurrir mientras se hace operaciones DML en paralelo, mientras se realiza una la actualización / eliminación de datos de mismas tablas de diferentes sesiones, al realizar transacciones  y así sucesivamente, pero los escenarios mencionados son los más comunes.

¿Cómo Detectar un Deacklock? 
Oracle detecta automáticamente los Deadlocks y los resuelve revirtiendo una de las transacciones  participan en el bloqueo, liberando así un conjunto de recursos bloqueados por esa transacción. La sesión que se deshace observará como error Oracle ORA-00060: deadlock detected while waiting for resource. Oracle también producirá información detallada en un archivo de rastreo en las bases de datos en el directorio udump


Mayormente estos Deadlocks son causados ​​por las aplicaciones que implican cambios de varias tablas en la misma transacción y múltiples operaciones están actuando en la misma tabla al mismo tiempo. 


miércoles, 7 de mayo de 2014

Vistas en PL/SQL



Concepto
Una Vista(View) es una presentación adaptada de los datos registrados en una o más tablas u otras vistas. Una vista toma la salida de una consulta y la trata como una tabla. Por lo tanto, una vista puede ser pensado como una consulta almacenada o una tabla virtual. 

Por ejemplo,la tabla empleados tiene varias columnas y varias filas de información. Si desea que los usuarios vean sólo cinco de estas columnas o filas específicas, entonces usted puede crear una vista de la tabla para que otros usuarios tengan acceso.

Por lo tanto,una vista es una consulta, que refleja el contenido de una o más tablas, desde la que se puede acceder a los datos como si fuera una tabla.Dos son las principales razones por las que podemos crear vistas.
  • Seguridad: nos pueden interesar que los usuarios tengan acceso a una parte de la información que hay en una tabla, pero no a toda la tabla.
  • Comodidad: Una vista ayuda a simplificar la consulta a datos específicos. 
Las vistas no tienen una copia física de los datos, son consultas a los datos que hay en las tablas, por lo que si actualizamos los datos de una vista, estamos actualizando realmente la tabla, y si actualizamos la tabla estos cambios serán visibles desde la vista.

Nota: No siempre podremos actualizar los datos de una vista, dependerá de la complejidad de la misma (dependerá de si el conjunto de resultados tiene acceso a la clave principal de la tabla o no), y del gestor de base de datos. No todos los gestores de bases de datos permiten actualizar vistas, ORACLE, por ejemplo, no lo permite, mientrar que SQL Server si.


Creación
Para crear una vista debemos utilizar la sentencia CREATE VIEW, debiendo proporcionar un nombre a la vista y una sentencia SQL SELECT válida.

CREATE VIEW
AS  ();

Ejemplo:Crear una vista sobre nuestra tabla empleados, donde se muestren ciertos datos

CREATE OR REPLACE VIEW Staff
AS( SELECT employee_id,
       last_name,
       job_id,
       manager_id,
      departament_id
FROM employees)

Si queremos, modificar la definición de nuestra vista tan solo se debe agregar la nueva columna. Al usar CREATE OR REPLACE VIEW podemos modificar la vista cuando se necesite. Nota: Se sugiere siempre crear vistas bajo este comando para futuras modificaciones

Por último podemos eliminar la vista a través de la sentencia DROP VIEW. Para eliminar la vista que hemos creado anteriormente se usa el siguiente comando:

DROP VIEW Staff;

martes, 18 de marzo de 2014

Uso del comando HINT


Los hints son sirven para que el optimizador SQL de Oracle  elabore el plan de ejecución de una sentencia DML (sentencias de manipulación de datos como select, insert, update, delete, etc).Los hints, hablando desde un punto de vista práctico, no son muy utilizados, aunque no por ello pueden dejar de ser útiles en determinadas circunstancias.


Los hints se incorporan a una sentencia DML en forma de comentario y deben ir justo detrás del comando principal. Por ejemplo, si se tratara de una sentencia SELECT el formato sería el siguiente:

     SELECT /*+ COMANDO-HINT */ ...

Los hints usados son los siguientes:

/*+ RULE */ - Fuerza a que se utilice el optimizador basado en normas (rule-based optimizer). Con este optimizador los planes de ejecución cambían según sea la sintaxis de la sentencia DML, no utiliza las estadísticas asociadas con las tablas de la base de datos Oracle y no calcula los costes del plan de ejecución. El optimizador basado en normas no ha cambiado desde la versión 6 de Oracle.

/*+ CHOOSE */ - Fuerza a que se utilice el optimizador basado en costes (cost-based optimizer). Este optimizador construye los planes de ejecución basándose en las estadísticas almacenadas en el diccionario de datos. Tiene en consideración el número de lectura lógicas (el factor más importante), la utilización de la CPU junto con los accesos a disco y a memoria, y el uso de la red (cuando los datos residen en diferentes servidores). Una de las ventajas de utilizar el optimizador basado en costes es que Oracle lo está mejorándolo continuamente.

/*+ ALL_ROWS */ - Fuerza a que se utilice el optimizador basado en costes y optimiza el plan de ejecución de la sentencia DML para que devuelva todas las filas en el menor tiempo posible. Es la opción por defecto del optimizador basado en costes y es la solución apropiada para procesos en masa e informes, en los que son necesarias todas las filas para empezar a trabajar con ellas.

/*+ FIRST_ROWS (n) */ - También fuerza a que se utilice el optimizador basado en costes y optimiza el plan de ejecución de la sentencia DML para que devuelva las "n" primeras filas en el menor tiempo posible. Esto es idóneo para procesos iterativos y bucles, en los que podemos ir trabajando con las primeras filas mientras se recuperan el resto de resultados. Obviamente este hint no será considerado por el optimizador si se utilizan funciones de grupo como MAX, SUM, AVG, etc.

La sentencia MERGE

La sentencia Merge nos sirve para combinar dos operaciones: Insertar y Actualizar. La función Merge nos permite hacer un update en caso de que la condición dada se cumpla o insertar en caso de que no se cumpla, es realmente muy útil.

Se puede usar a partir de Oracle 9i.


Ventajas:

  • Permite con una misma sentencia realizar un UPDATE si el registro existe, o un INSERT si se trata de un nuevo registro inserta desde ORIGEN a DESTINO.   
  • Se evita la necesidad de realizar actualizaciones multiples.  
  • Es especialmente útil para realizar operaciones en masa.   
  • Al necesitarse menos sentencias SQL para realizar las mismas operaciones, también se necesitan menos accesos a las tablas fuente, o sea que se mejora el rendimiento de la DB y si fuera una app para el usuario la tasa de respuesta a este.
  • Si por ejemplo nuestra condicion fuera fecha, sucursal, o lo que te interese, podriamos poner esto en un crontab o una vista materializara y bien que podriamos crear un cubo

La sintaxis:

MERGE INTO <table_name>
USING <table_view_or_query>
ON (<condition>)
WHEN MATCHED THEN <update_clause>
WHEN NOT MATCHED THEN <insert_clause>
[LOG ERRORS <log_errors_clause> <reject limit <integer | unlimited>];


TABLE_NAME
Aqui debe especificar el nombre de la tabla o vista en la que va a insertar o actualizar. Si va a hacer un merge sobre una vista, ésta debe ser actualizable.


TABLE_VIEW_OR_SUBQUERY

En está se indica el origen de los datos que va a actualizar, puede ser una tabla, una vista o un subquery.

CONDITION
Especificas la condición para que el merge decida si debe actualizar o insertar. Esta condición es evaluada fila por fila, si la condición es verdadera, se ejecutará la clausula Update; si la condición es falsa, la base de datos insertará el registro desde el origen.

UPDATE_CLASE 
Especifica los nuevos valores de la tabla a actualizar, en caso de que la condición sea verdadera. No puedes actualizar una columna que éste incluida en la Condición.


INSERT_CLAUSE

Especifíca los valores a insertar en caso de que la condición no sea verdadera. 

EJEMPLO

En el ejemplo tenemos una tabla de descuentos a clientes (desc_client), está llena con los clientes de la empresa con derecho a descuento hasta el momento. La tabla está asi
Id     Porc_desc
111      10
112      10
115      15
212      20
Vamos a hacer una sentencia para que a los clientes que han comprado más de 200 pesos en el año se les incluya en la tabla de descuentos con un 10% y a los que ya están se les suba le 1% (Es solo un ejemplo)

La sentencia sería:

MERGE INTO desc_client d
USING (select id, sum(valor) from facturas where anio=2012
       group by id having sum(valor)>200) f
ON (d.id=f.id)
WHEN MATCHED THEN update set d.porc_desc = d.porc_desc + 1
WHEN NOT MATCHED THEN insert (d.id, d.porc_desc)
values (f.id, 10);


El resultado, suponiendo que los clientes 111,115,205,206 superaron los 200 pesos en compras, sería:

Id     Porc_desc
111      11
112      10
115      16
212      20
205      10
206      10


Por ultimo, MERGE es una operacion DML exactamente como update/insert por lo que es necesario correr commit para que los cambios tengan efecto