Manual de Oracle 10g

41
Manual de Oracle Tabla resumen de tipos de datos. Tipo Dato Descripción VARCHAR2(size [BYTE | CHAR]) Cadena de caracteres de longitud variable que tiene como tamaño máximo el valor de size en BYTE o CHAR. El tamaño máximo es de 4000 bytes o caracteres, y la mínima es de 1 byte o un carácter. Se debe especificar el tamaño de para VARCHAR2. NVARCHAR2(size) Cadena de caracteres Unicode de longitud variable con size como máximo tamaño de longitud. El número de bytes que pueden ser hasta dos veces el tamaño de codificación AL16UTF16 y tres veces el tamaño de la codificación UTF8. El tamaño máximo está determinado por la definición del juego de caracteres nacional, con un límite máximo de 4000 bytes. Se debe especificar el size de NVARCHAR2. NUMBER [ (p [, s]) ] Número con p precisión (parte entera) y s escala (parte decimal). La precisión p puede variar de 1 a 38. La s escala puede variar desde -84 hasta 127. Tanto la precisión y la escala se encuentran en dígitos decimales. Un valor numérico requiere 1 a 22 bytes. FLOAT [(p)] Un subtipo del tipo de datos NUMBER con precisión p. Un valor de coma flotante se representa internamente como un NUMBER. La precisión p puede variar desde 1 hasta 126 dígitos binarios. Un valor flotante requiere 1 a 22 bytes. LONG Tipo de datos de caracteres de longitud variable de hasta 2 gigabytes, o 2 31 -1 bytes. Permanece para compatibilidad con versiones anteriores de Oracle. DATE Intervalo de fechas válidas del 1 de enero de 4712 antes de Cristo a el 31 de diciembre de 9999. El formato por defecto se determina explícitamente por el parámetro NLS_DATE_FORMAT o implícitamente por el parámetro NLS_TERRITORY. El tamaño es de 7 bytes. Este tipo de datos contiene los campos de fecha y hora AÑO, MES, día, hora, minuto y segundo. No tiene fracciones de segundo o de una zona horaria. BINARY_FLOAT Número en coma flotante de 32 bits. Este tipo de datos requiere 4 bytes. BINARY_DOUBLE Número en coma flotante de 64 bits. Este tipo de datos se requieren de 8 bytes. TIMESTAMP [(fractional_seconds_precision)] Año, mes y día como valores de la fecha, así como la hora, minutos y segundos como valores de tiempo, donde fractional_seconds_precision es el número de dígitos en la parte fraccionaria del segundo del campo datetime. Los valores aceptados de fractional_seconds_precision son del 0 al 9. El valor por defecto es 6. El formato por defecto se determina explícitamente por el parámetro NLS_TIMESTAMP_FORMAT o implícitamente por el

Transcript of Manual de Oracle 10g

Page 1: Manual de Oracle 10g

Manual de OracleTabla resumen de tipos de datos.

Tipo Dato Descripción

VARCHAR2(size [BYTE | CHAR]) Cadena de caracteres de longitud variable que tiene como  tamaño máximo el valor de size en BYTE o CHAR. El tamaño máximo es de 4000 bytes o caracteres, y la mínima es de 1 byte o un carácter. Se debe especificar el tamaño de para VARCHAR2.

NVARCHAR2(size) Cadena de caracteres Unicode de longitud variable con size como máximo tamaño de longitud. El número de bytes que pueden ser hasta dos veces el tamaño de codificación AL16UTF16 y tres veces el tamaño de la codificación UTF8. El tamaño máximo está determinado por la definición del juego de caracteres nacional, con un límite máximo de 4000 bytes. Se debe especificar el size de NVARCHAR2.

NUMBER [ (p [, s]) ] Número con p precisión (parte entera) y s escala (parte decimal). La precisión p puede variar de 1 a 38. La s escala puede variar desde -84 hasta 127. Tanto la precisión y la escala se encuentran en dígitos decimales. Un valor numérico requiere 1 a 22 bytes.

FLOAT [(p)] Un subtipo del tipo de datos NUMBER con precisión p. Un valor de coma flotante se representa internamente como un NUMBER. La precisión p puede variar desde 1 hasta 126 dígitos binarios. Un valor flotante requiere 1 a 22 bytes.

LONG Tipo de datos de caracteres de longitud variable de hasta 2 gigabytes, o 231 -1 bytes. Permanece para compatibilidad con versiones anteriores de Oracle.

DATE Intervalo de fechas válidas del 1 de enero de 4712 antes de Cristo a el 31 de diciembre de 9999. El formato por defecto se determina explícitamente por el parámetro NLS_DATE_FORMAT o implícitamente por el parámetro NLS_TERRITORY. El tamaño es de 7 bytes. Este tipo de datos contiene los campos de fecha y hora AÑO, MES, día, hora, minuto y segundo. No tiene fracciones de segundo o de una zona horaria.

BINARY_FLOAT Número en coma flotante de 32 bits. Este tipo de datos requiere 4 bytes.

BINARY_DOUBLE Número en coma flotante de 64 bits. Este tipo de datos se requieren de 8 bytes.

TIMESTAMP [(fractional_seconds_precision)] Año, mes y día como valores de la fecha, así como la hora, minutos y segundos como valores de tiempo, donde fractional_seconds_precision es el número de dígitos en la parte fraccionaria del segundo del campo datetime. Los valores aceptados de fractional_seconds_precision son del 0 al 9. El valor por defecto es 6. El formato por defecto se determina explícitamente por el parámetro NLS_TIMESTAMP_FORMAT o implícitamente por el parámetro NLS_TERRITORY. El tamaño es de 7 o 11 bytes, dependiendo de la precisión. Este tipo de datos contiene los campos datetime AÑO, MES, DIA, HORA, MINUTO y SEGUNDO. Contiene las fracciones de segundo, pero no tiene una zona horaria.

TIMESTAMP [(fractional_seconds_precision)] WITHTIMEZONE

Todos los valores de TIMESTAMP, así como el valor de tiempo de desplazamiento de la zona, donde fractional_seconds_precision es el número de dígitos en la parte fraccionaria del segundo del campo datetime. Los valores aceptados son del 0 al 9. El valor por defecto es 6. El formato por defecto se determina explícitamente por el parámetro NLS_TIMESTAMP_FORMAT o implícitamente por el parámetro NLS_TERRITORY. El tamaño se fija en 13 bytes. Este tipo de datos contiene los campos datetime AÑO, MES, DIA, HORA, MINUTO, SEGUNDO, TIMEZONE_HOUR y TIMEZONE_MINUTE. Cuenta con las fracciones de segundo y una zona horaria explícita.

TIMESTAMP [(fractional_seconds)] WITHLOCALTIMEZONE

Todos los valores de TIMESTAMP WITHTIMEZONE, con las siguientes excepciones:

Page 2: Manual de Oracle 10g

Manual de Oracle* Los datos se normalizan con la zona horaria de base de datos cuando se almacenan en la base de datos.* Cuando se recuperan los datos, los usuarios ven los datos en la zona de tiempo de la sesión.

El formato por defecto se determina explícitamente por el parámetro NLS_TIMESTAMP_FORMAT o implícitamente por el parámetro NLS_TERRITORY. El tamaño es de 7 o 11 bytes, dependiendo de la precisión.

INTERVALYEAR [(year_precision)] TOMONTH

Almacena un período de tiempo en años y meses, donde year_precision es el número de dígitos en el campo datetime AÑO. Los valores aceptados son del 0 al 9. El valor predeterminado es 2. El tamaño se fija en 5 bytes.

INTERVALDAY [(day_precision)] TOSECOND [(fractional_seconds)]

Almacena un período de tiempo en días, horas, minutos y segundos, donde

* day_precision es el número máximo de dígitos en el campo datetime DÍA. Los valores aceptados son del 0 al 9. El valor predeterminado es 2.* fractional_seconds_precision es el número de dígitos en la parte fraccionaria del campo SEGUNDO. Los valores aceptados son del 0 al 9. El valor por defecto es 6.

El tamaño se fija en 11 bytes.

RAW(size) Datos binarios sin formato de longitud size. El tamaño máximo es de 2000 bytes. Se debe especificar el tamaño de un valor RAW.

LONG RAW Datos binarios de tipo RAW de longitud variable hasta 2 gigabytes.

ROWID Cadena en base 64 que representa la dirección única de una fila en la tabla. Este tipo de datos es principalmente para los valores devueltos por la pseudo columna ROWID.

UROWID [(size)] Cadena en base 64 que representa la dirección lógica de una fila de una tabla de índice organizado. El tamaño opcional es el tamaño de una columna de tipo UROWID de Oracle. El tamaño máximo y por defecto es de 4000 bytes.

CHAR [(size [BYTE | CHAR])] Cadena de caracteres de longitud fija de size bytes de tamaño o size de caracteres. El tamaño máximo es de 2000 bytes o caracteres, el tamaño predeterminado y mínimo es de 1 byte.

NCHAR[(size)] Cadena de caracteres de longitud fija de size caracteres de tamaño de largo. El número de bytes pueden ser hasta dos veces el tamaño de codificación AL16UTF16 y tres veces el tamaño de la codificación UTF8. El tamaño máximo está determinado por la definición del juego de caracteres nacional, con un límite máximo de 2000 bytes. El tamaño predeterminado y mínimo es de un carácter.

CLOB Un objeto de tipo LOB que contiene caracteres de un byte o multibyte. Son compatibles tanto de ancho fijo y conjuntos de ancho variable de caracteres, con el carácter de base de datos establecida. El tamaño máximo es (4 gigabytes - 1) * (tamaño del bloque de la base de datos).

NCLOB Un objeto de tipo LOB que contiene caracteres Unicode. Son compatible tanto de ancho fijo y conjuntos de ancho variable de caracteres, con el conjunto base de datos de carácter nacional. El tamaño máximo es (4 gigabytes - 1) * (tamaño del bloque de la base de datos). Guarda los datos nacionales sobre el conjunto de caracteres.

BLOB Un objeto de tipo LOB binario. El tamaño máximo es (4 gigabytes - 1) * (tamaño del bloque de la base de datos).

BFILE Contiene un localizador a un archivo binario almacenado fuera de la base de datos. Permite flujo de bytes de E/S para el acceso a LOB externos que residen en el servidor de base de datos. El tamaño máximo es de 4 gigabytes.

Page 3: Manual de Oracle 10g

Manual de Oracle

Page 4: Manual de Oracle 10g

Manual de Oracle

Práctica Cambiar un valor null por otro

La función NVL() te permite sustituir valores null con una cadena en los resultados de una consulta. Si expr1 es nulo, NVL devuelve expr2. Si expr1 no es nulo, NVL devuelve expr1.

Los argumentos expr1 y expr2 pueden tener cualquier tipo de dato. Si sus tipos de datos son diferentes, entonces la base de datos Oracle convierte implícitamente al otro. Si no se puede convertir de forma implícita, la base de datos devuelve un error. La conversión implícita se lleva a cabo de la siguiente manera:

 Si expr1 es de tipo carácter, la base de datos Oracle convierte expr2 al tipo de datos de expr1 antes de compararlos y devuelve un VARCHAR2 en el juego de caracteres de expr1

 Si expr1 es de tipo numérico, base de datos Oracle determina qué argumento tiene la máxima prioridad numérica, convierte implícitamente el argumento válido para ese tipo de datos, y devuelve ese tipo de datos

 La función NVL() se puede utilizar tanto en Oracle 10g como en Oracle 11g.

  Ejemplos

En este ejemplo aparece un listado de productos con su descuento, si descuento es null colocamos un 0.

1.SELECTDescripcion, NVL(TO_CHAR(descuento), 0) Descuento 2. FROMproductos3. WHEREprecio< 12 4. ORDERBY 1;

DESCRIPCION              DESCUENTO---------------------------     --------------Cuaderno anillas 10 A4    0Grapadora pequeña        10Paquete 500 folios A4      0Portaminas 0.5              2Rotulador rojo               4

En este otro ejemplo si descuento es null colocamos una cadena de caracteres ‘Sin Descuento’.

1.SELECTDescripcion, NVL(TO_CHAR(descuento), 'Sin Descuento') Descuento 2. FROMproductos3. WHEREprecio< 12 4. ORDERBY1;

Page 5: Manual de Oracle 10g

Manual de OracleDESCRIPCION              DESCUENTO-----------------------         ---------------Cuaderno anillas 10 A4    Sin DescuentoGrapadora pequeña       10Paquete 500 folios A4     Sin DescuentoPortaminas 0.5             2Rotulador rojo              4

Page 6: Manual de Oracle 10g

Manual de Oracle

Práctica Índices

Definición de índice ¿Qué es un índice? ¿Para qué sirve?

El índice de una base de datos es una estructura de datos que mejora la velocidad de las operaciones, permitiendo un rápido acceso a los registros de una tabla. Al aumentar drásticamente la velocidad de acceso, se suelen usar sobre aquellos campos sobre los cuales se vayan a realizar búsquedas frecuentes.

El índice tiene un funcionamiento similar al índice de un libro, guardando parejas de elementos: el elemento que se desea indexar y su posición en la base de datos. Para buscar un elemento que esté indexado, sólo hay que buscar en el índice de dicho elemento para, una vez encontrado, devolver el registro que se encuentre en la posición marcada por el índice.

Los índices pueden ser creados usando una o más columnas, preparando la base de datos tanto para búsquedas rápidas al azar como para ordenaciones eficientes de los registros.

Los índices son construidos sobre árboles B, B+, B* o sobre una mezcla de ellos, funciones de cálculo u otros métodos.

El espacio en disco requerido para almacenar el índice es típicamente menor que el espacio de almacenamiento de la tabla (puesto que los índices generalmente contienen solamente los campos clave de acuerdo con los que la tabla será ordenada, y excluyen el resto de los detalles de la tabla), lo que da la posibilidad de almacenar en memoria los índices de tablas que no cabrían en ella. En una base de datos relacional un índice es una copia de parte de una tabla.

Crearemos una tabla para el ejemplo de creación de índices ejecutando la siguiente consulta SQL:

CREATE TABLE facturacion (codigonumber(10) notnull,fecha date default sysdate,codigoclientenumber(10),nombreclientevarchar(100),observacionvarchar(2000),constraintpk_facturacion_codigoprimarykey (codigo)) tablespace USERS

Como se puede observar en la consulta SQL anterior, al añadir la línea:

Constraint pk_facturacion_codigo primary key (codigo)

Page 7: Manual de Oracle 10g

Manual de OracleEstamos indicando a Oracle que cree la tabla "facturacion", con el campo "codigo" y que éste sea clave primaria, por lo que creará un índice automáticamente para este campo. Esta es una forma de crear índices, en la creación de la tabla:

Tras crear la tabla insertaremos algunos registros con la instrucción SQL:

Insert into facturacion (codigo, codigocliente, nombrecliente) values (1, 50, 'AletsLorat')

Puesto que hemos indicado que la columna "codigo" sea clave primaria, Oracle no permitirá valores duplicados para esta columna, esta comprobación la realizará basándose en el índice creado. Si intentamos agregar un nuevo registro con el valor de "codigo" a "1" (que ya existe) nos mostrará este error:

Con el texto: ORA-00001: restricción única (SYSTEM.PK_FACTURACION_CODIGO) violada, indicando que la restricción única PK_FACTURACION_CODIGO no se ha cumplido por lo que no dejará insertar el registro.

Insertaremos varios registros (cambiando el valor de "codigo"). Ejecutando la consulta SQL:

select * from facturacion

Crear un índice en una tabla que ya existente en Oracle

La creación de un índice en Oracle se realiza mediante el comando createindex. Cuando se define una clave primaria o una columna unívoca (UNIQUE) durante la creación de una tabla o su mantenimiento, Oracle creará automáticamente un índice de tipo UNIQUE que gestione dicha restricción, como hemos indicado anteriormente. La sintaxis completa de createindexes la siguiente:

create [bitmap | unique] indexnombre_indiceonnombre_tabla (nombre_columna [, nombre_columna2] ...) [reverse];

bitmap indica que se cree un índice de mapa de bits que permite crear índices en columnas con muy pocos valores diferentes.

unique indica que el valor de la o las columnas indexadas debe ser único, no puede haber duplicidades.

nombre_indicedebe ser un nombre unívoco (no debe existir otro nombre de objeto en Oracle) que siga los convenios de denominación de Oracle para nombrar columnas.

nombre_tabla será el nombre de la tabla donde se creará el índice. nombre_columna (o columnas) será la columna de la tabla nombre_tabla en la que

se creará el índice. Se puede crear un índice para varias columnas.

Page 8: Manual de Oracle 10g

Manual de Oracle reverse indica a Oracle que invierta los bytes del valor indexado, lo que puede

mejorar la distribución del procesamiento y de los datos cuando se insertan muchos valores de datos secuenciales.

Para crear un índice en Oracle podemos utilizar SQL*Plus (herramienta de línea de comandos incluida con Oracle), se puede utilizar Oracle Enterprise Manager (modo gráfico) o una aplicación externa que permita acceso a Oracle, como por ejemplo:

Siguiendo con el ejemplo, añadiremos un índice normal para la columna "nombrecliente" de la tabla "facturacion". Para ello ejecutaremos la siguiente consulta SQL:

CREATE INDEX facturacionCte ON facturacion(NombreCliente);

Para ver el índice creado podemos ejecutar la siguiente consulta SQL (como indicamos aquí):

Select index_name as Nombre, index_type as Tipo,table_name as Tabla, tablespace_name as Tablespace,secondary as Secundariofrom all_indexeswhere table_name = 'FACTURACION';

Para añadir un índice de tipo UNIQUE, obligando a que los valores del campo indexado sean unicos, no se puedan repetir en el campo de la tabla, ejecutaremos la siguiente sentencia SQL:

Create unique index IN_FACTURACION_COD_CODCLI_FEon FACTURACION (CODIGOCLIENTE, FECHA)

De esta forma Oracle no permitirá que haya dos registros en la tabla "facturacion" con el mismo valor en los campos "codigocliente" y "fecha", es decir, sólo podrá añadirse una factura por cliente y por día, un cliente no podrá tener dos facturas en un mismo día. Por ejemplo, si insertamos este registro:

Insert into facturacion(codigo, codigocliente, fecha)values (6900, 500, to_date('31/12/2009', 'DD-MM-YYYY'))

Intentaremos insertar un segundo registro con el mismo valor en codigocliente y en fecha:

Insert into facturacion(codigo, codigocliente, fecha)values (6910, 500, to_date('31/12/2009', 'DD-MM-YYYY'))

Oracle detectará que se está intentando infringir una restricción única, por lo que mostrará el siguiente mensaje de error y no dejará que se inserte el registro:

Page 9: Manual de Oracle 10g

Manual de OracleCon el texto: ORA-00001: restricción única (SYSTEM.IN_FACTURACION_COD_CODCLI_FE) violada.

Cómo saber si un índice se está utilizando, monitorización del uso de índices en Oracle

Para consultar las estadísticas sobre el uso de uno o varios índices de tablas de Oracle, en primer lugar deberemos activar la monitorización del índice que queramos, para ello utilizaremos el siguiente comando SQL:

Alter index nombre_indice monitoring usage;

Por ejemplo, en nuestro caso, para monitorizar el índice IN_FACTURACION_NOMBRECLIENTE:

Alter index IN_FACTURACION_NOMBRECLIENTE monitoring usage;

Tras activar la monitorización, podremos ver si el índice ha sido usado ejecutando la siguiente consulta SQL. En nuestro caso comprobaremos si han sido usados los índices monitorizados de la tabla FACTURACION:

select *from v$object_usagewhere table_name = 'FACTURACION'

Mostrará un registro indicando los siguientes datos:

INDEX_NAME: nombre del índice usado. TABLE_NAME: nombre de la tabla a la que pertenece el índice usado. MONITORING: estado de monitorización, si está activa mostrará "YES". USED: mostrará "NO" si aún no ha sido usado. START_MONITORING: fecha y hora de inicio de monitorización. END_MONITORING: fecha y hora de fin de monitorización.

Si insertamos algunos registros en la tabla FACTURACION y hacemos alguna consulta SQL ordenando por "nombre_cliente" para que el índice sea usado podremos ver cómo cambia el valor de USED en v$object_usage:

Para desactivar la monitorización ejecutaremos el siguiente comando SQL:

Alter index nombre_indiceno monitoring usage;

En nuestro ejemplo:

Alter index IN_FACTURACION_NOMBRECLIENTE nomonitoring usage

Page 10: Manual de Oracle 10g

Manual de OracleEjecutando nuevamente la consulta:

select *from v$object_usagewhere table_name = 'FACTURACION'

Veremos que ha cambiado el valor de MONITORING a "NO" y ha añadido la fecha y hora a END_MONITORING.

Mostrar información de los índices de una tabla en Oracle

Mostrar todas las restricciones de una tabla de Oracle

Para mostrar todas las restricciones de una tabla oracle (nombre de la restricción, nombre de la tabla, columnas a las que afecta) ejecutaremos la siguiente consulta SQL:

Select constraint_nameNombre, table_nameTabla,substr(column_name, 1, 255) Columnasfrom all_cons_columnswhere table_name = 'FACTURACION'

Mostrar todos los índices de una tabla en Oracle

La siguiente consulta SQL mostrará todos los índices de la tabla "FACTURACION" de Oracle (nombre del índice, tipo de índice, nombre de la tabla, tablespace en el que se guarda, si es secundario):

Select index_name Nombre, index_type Tipo, table_name Tabla, tablespace_name Tablespace, secondary Secundariofrom all_indexeswhere table_name = 'FACTURACION'

Obtener el tamaño ocupado por un índice de una tabla de Oracle

La siguiente consulta SQL mostrará el tamaño en megabytes de un índice determinado, en nuestro caso del índice PK_FACTURACION_CODIGO perteneciente a la tabla FACTURACION y el campo CODIGO del ejemplo. La consulta SQL para mostrar el tamaño ocupado por un índice es la siguiente:

Select segment_name, sum(bytes)/1024/1024 MBfrom dba_extents

Page 11: Manual de Oracle 10g

Manual de Oraclewhere segment_name = 'PK_FACTURACION_CODIGO'group by segment_name

Reconstrucción de índices ¿cúando es necesaria? ¿cómo hacerla?, parámetros de los índices en Oracle

Reconstruir índices en Oracle

Oracle proporciona la capacidad de realizar una reconstrucción rápida de índices, que permite crear de nuevo un índice sin necesidad de eliminar el índice existente. El índice actualmente disponible se usa como origen de datos para el índice nuevo, en lugar de utilizar la tabla como origen de datos. Durante la reconstrucción del índice pueden cambiarse los parámetros de almacenamiento (storage) y la asignación del espacio de tablas (tablespace).

Para reconstruir un índice de una tabla utilizaremos la cláusula rebuild con el comando alter index. Un ejemplo de reconstrucción de un índice en Oracle podría ser:

ALTER INDEX nombre_indice REBUILD;

Siguiendo nuestro ejemplo, para reindexar el índice PK_FACTURACION_CODIGO ejecutaremos la siguiente instrucción SQL:

ALTER INDEX PK_FACTURACION_CODIGO REBUILD;

Ejecutaremos esta consulta desde Oracle Enterprise Manager, accediendo a la opción "Hoja de Trabajo de SQL", desmarcaremos la opción "Permitir Sólo Sentencias SELECT", en "Comandos SQL" introduciremos:

ALTER INDEX PK_FACTURACION_CODIGO REBUILD;

Y pulsaremos en "Ejecutar". Si todo es correcto nos devolverá en "Resultados": SQL se ha ejecutado correctamente.

Cambiar los parámetros de configuración de un índice en Oracle

Si queremos cambiar algún parámetro de configuración de algún índice, como el almacenamiento (storage) o incluso el espacio de tablas (tablespace) podremos ejecutar la siguiente instrucción SQL:

alter index nombre_indice rebuildstorage (initial 8M next 4M)tablespacenombre_tablespace;

Page 12: Manual de Oracle 10g

Manual de OracleCon la instrucción anterior se reconstruirá el índice "nombre_indice" asignándole un tamaño inicial de extensión de 8MB y un tamaño para las siguientes extensiones de 4MB. El índice "nombre_indice" será creado en el tablespace "nombre_tablespace". Por lo que esta instrucción SQL servirá para cambiar de tablespace un índice (si así lo deseamos).

 

Page 13: Manual de Oracle 10g

Manual de OracleIntegridadPara preservar la consistencia y corrección de los datos almacenados, un DBMS relacional impone generalmente una o más restricciones de integridad de datos. Estas restricciones restringen los valores que pueden ser insertados en la base de datos o creados mediante una actualización de la base de datos.

Este tipo de integridad se demostró en la Práctica Índices vista en el tema anterior.

Integridad de Entidad

La integridad de entidad define una fila como entidad única para una tabla determinada. La integridad de entidad fuerza la integridad de la columna o columnas de los identificadores o la clave principal de una tabla (mediante índices, restricciones UNIQUE y restricciones PRIMARY KEY).

Integridad Referencial

La integridad referencial garantiza la coherencia de la información entre dos tablas que se encuentran relacionadas, de manera que se garantice que no efectué el cambio sí:

Agregar registros a una tabla relacionada si no hay ningún registro asociado en la tabla principal.

Cambiar valores en una tabla principal de manera que queden registros huérfanos en una tabla relacionada.

Oracle sólo admite dos tipos de integridad referencial:

Activar la integridad referencial para comprobar los valores de las tablas relacionadas al especificar los datos. Si el valor del dato no está permitido (determinado por las reglas definidas anteriormente), se produce un error en la entrada de datos y no se agregan a la base de datos.

Eliminaciones en cascada.

Para implementar la integridad referencial contamos con: Foreign Key. Si intentamos eliminar un registro de la tabla referenciada por una restricción "foreign key" cuyo valor de

Page 14: Manual de Oracle 10g

Manual de Oracleclave primaria existe referenciada en la tabla que tiene dicha restricción, la acción no se ejecuta y aparece un mensaje de error. Esto sucede porque, por defecto, para eliminaciones, la opción de la restricción "foreign key" es "no action".

La restricción "foreign key" tiene la cláusula "on delete", que son opcionales. Esta cláusula especifica cómo debe actuar Oracle frente a eliminaciones en las tablas referenciadas en la restricción.

Las opciones para estas cláusulas son las siguientes:

"set null": indica que si eliminamos un registro de la tabla referenciada (TABLA2) cuyo valor existe en la tabla principal (TABLA1), dicho registro se elimine y los valores coincidentes en la tabla principal se seteen a "null".

"cascade": indica que si eliminamos un registro de la tabla referenciada en una "foreign key" (TABLA2), los registros coincidentes en la tabla principal (TABLA1), también se eliminen; es decir, si eliminamos un registro al cual una clave foránea referencia, dicha eliminación se extiende a la otra tabla (integridad referencial en cascada).

"no action": es la predeterminada; indica que si se intenta eliminar un registro de la tabla referenciada por una "foreign key", Oracle no lo permita y muestre un mensaje de error. Se establece omitiendo la cláusula "on delete" al establecer la restricción.

La sintaxis completa paar agregar esta restricción a una tabla es la siguiente:

alter table TABLA1 add constraint NOMBRERESTRICCION foreign key (CAMPOCLAVEFORANEA) references TABLA2(CAMPOCLAVEPRIMARIA) on delete OPCION;

Veamos un ejemplo. Definimos una restricción "foreign key" a la tabla "libros" estableciendo el campo "codigoeditorial" como clave foránea que referencia al campo "codigo" de la tabla "editoriales". La tabla "editoriales" tiene como clave primaria el campo "codigo". Especificamos la acción en cascada para las eliminaciones:

alter table libros add constraint FK_libros_codigoeditorial foreign key (codigoeditorial) references editoriales(codigo) on delete cascade;

Page 15: Manual de Oracle 10g

Manual de OracleSi luego de establecer la restricción anterior, eliminamos una editorial de "editoriales" cuyo valor de código está presente en "libros", se elimina dicha editorial y todos los libros de tal editorial.

Si consultamos "user_constraints", en la columna "delete_rule" mostrará "cascade".

Para definir una restricción "foreign key" sobre la tabla "libros" estableciendo el campo "codigoeditorial" como clave foránea que referencia al campo "codigo" de la tabla "editoriales" especificando la acción de seteo a "null" tipeamos:

alter table libros add constraint FK_libros_codigoeditorial foreign key (codigoeditorial) references editoriales(codigo) on delete set null;

Si luego de establecer la restricción anterior, eliminamos una editorial de "editoriales" cuyo valor de código está presente en "libros", se elimina dicha editorial y todos los valores de libros que coinciden con tal editorial se setean a null. Si consultamos "user_constraints", en la columna "delete_rule" mostrará "set null".

Sintetizando, si al agregar una restricción "foreign key":

No se especifica acción para eliminaciones, y se intenta eliminar un registro de la tabla referenciada en la "foreign key" (editoriales) cuyo valor de clave primaria (codigo) existe en la tabla principal (libros), la acción no se realiza.

Se especifica "cascade" para eliminaciones ("on delete cascade") y elimina un registro de la tabla referenciada (editoriales) cuyo valor de clave primaria (codigo) existe en la tabla principal(libros), la eliminación de la tabla referenciada (editoriales) se realiza y se eliminan de la tabla principal (libros) todos los registros cuyo valor coincide con el registro eliminado de la tabla referenciada (editoriales).

Se especifica acción para eliminaciones ("on delete set null") y se elimina un registro de la tabla referenciada en la "foreign key" (editoriales) cuyo valor de clave primaria (codigo) existe en la tabla principal (libros), la acción se realiza y se setean a "null" todos los valores coincidentes en la tabla principal (libros).

Page 16: Manual de Oracle 10g

Manual de OracleLa restricción "foreign key" NO tiene una cláusula para especificar acciones para actualizaciones.

Si intentamos actualizar un registro de la tabla referenciada por una restricción "foreign key" cuyo valor de clave primaria existe referenciada en la tabla que tiene dicha restricción, la acción no se ejecuta y aparece un mensaje de error. Esto sucede porque, por defecto (y como única opción), para actualizaciones existe "no action".

Integridad de Dominio

La integridad de dominio viene dada por la validez de las entradas para una columna determinada. Puede forzar la integridad de dominio si restringe el tipo (mediante tipos de datos), o el intervalo de valores posibles (mediante restricciones FOREIGN KEY, restricciones CHECK, definiciones DEFAULT, definiciones NOT NULL).

Tratamiento de valores Null en ORACLE.

Esta restricción especifica si una columna puede contener o no valores nulos. ORACLE por defecto se asume que la columna admite valores nulos.

Formato:

atributo tipo [CONSTRAINT nombre] NOT NULL | NULL.

Ejemplo:Dni integer CONSTRAINT nn_dni NOT NULL

Tratamiento de los valores defecto en ORACLE (DEFAULT).En este caso, las restricciones de integridad se utilizan para especificar valores que serán asignados a una columna, cuando en ésta no se introduzca ningún valor. El valor especificado en este campo debe ser del mismo tipo que la columna.

Las restricciones se especifican como parte de la definición de la columna.

Para el tratamiento de información faltante, se le puede especificar un NULL como valor por defecto siempre que la columna permita nulos.

Page 17: Manual de Oracle 10g

Manual de OracleEn la expresión no se puede hacer referencia a otras columnas.

Formato:

atributo tipo DEFAULT expresión.

Ejemplo:

Num integer DEFAULT 1+3.

Tratamiento de las restricciones de validez en ORACLE (CHECK)Las restricciones de integridad de dominio serán aquellas fórmulas bien formadas de primer orden construidas con atributos de la tabla como términos básicos, que depende satisfacerse en todos los estados válidos para las tuplas de una tabla.

Estas restricciones de integridad están especificadas en ORACLE dentro de una restricción de tipo CHECK asociada a una columna o una tabla.

La implementación de esta restricción en una columna sería:

Formato:

atributo tipo [CONSTRAINT nombre] CHECK condición.

Ejemplo:

Saldo integer CHECK saldo!=saldo_base

A diferencia de otros gestores, en esa condición se puede hacer referencia a cualquier columna de la tabla.

Si intentamos agregar una restricción que no permita que el precio mayorista supere el precio minorista:

alter table libros add constraint CK_libros_preciominmay check (preciomay<=preciomin);

No se pueden introducir en estas condiciones atributos de otras tablas. En ese caso, sólo queda el recurso de programar explícitamente la restricción de integridad, lo que habitualmente se hace generando disparos (“triggers”) de la base de datos.

Page 18: Manual de Oracle 10g

Manual de OracleIntegridad Definida por el Usuario

La integridad definida por el usuario permite definir reglas de empresa específicas que no pertenecen a ninguna otra categoría de integridad. Todas las categorías de integridad admiten la integridad definida por el usuario.

Triggers

Un disparador (o trigger) es un tipo especial de procedimiento almacenado asociado a una tabla que se ejecuta al realizar una operación “básica” (INSERT, un DELETE o un UPDATE) sobre ésta. La operación básica que despierta al trigger es conocida como sentencia disparadora.

La ejecución del disparador puede ser antes (before) o después (after) de llevar a cabo la sentencia disparadora. Es posible especificar condiciones adicionales para la ejecución del disparador (restrictores). Dado que una sentencia disparadora puede afectar una o más filas de una tabla, es necesario especificar si se quiere que el disparador se ejecute para cada una de las filas afectadas o para el bloque en general.

Para diseñar un disparador hay que cumplir dos requisitos:

Especificar las condiciones en las que se va a ejecutar el disparador. Esto se descompone en un evento que causa la comprobación del disparador y una condición que se debe cumplir para ejecutar el disparador.

Especificar las acciones que se van a realizar cuando se ejecute el disparador.

Los triggers PL/SQL constituyen una potente herramienta para mantener la integridad de la base de datos, ya que pueden llevar a cabo cualquier acción que sea necesaria para el mantenimiento de dicha integridad.

Los triggers PL/SQL pueden llamar a otros procedimientos y disparar otros triggers, pero no admiten parámetros y no pueden ser invocados desde otros procedimientos PL/SQL.

La sintaxis de un disparador Oracle es

CREATE [OR REPLACE] TRIGGER nombre{BEFORE | AFTER | INSTEAD OF} // Temporalidad del Evento{INSERT | DELETE | UPDATE [OF <lista de columnas>]} ON <tabla>

Evento

[FOR EACH ROW | STATEMENT] //Granularidad[WHEN condición]

Lógica

[DECLARE//Declaración de variables Código

Page 19: Manual de Oracle 10g

Manual de Oracle…]BEGIN

cuerpo del trigger[EXCEPTION…]END;

Suponga que se tienen las siguientes relaciones, asociadas a la concesión de préstamos en un banco:

Page 20: Manual de Oracle 10g

Manual de Oracle

Para implementar el diagrama entidad relación se tiene en Oracle el siguiente código

CREATE TABLE DEUDOR (IFE CHAR(13) NOT NULL,NOMBRE CHAR(50) NOT NULL,DIRECCION CHAR(100) NOT NULL,TELEFONO CHAR(10) NOT NULL,CONSTRAINT PKDeudor PRIMARY KEY (IFE) );

CREATE TABLE PRESTAMO (NPRESTAMO NUMBER(5) NOT NULL PRIMARY KEY,IFE CHAR(13) NULL UNIQUE REFERENCES Deudor(IFE),INTERES NUMBER(4,2) NOT NULL,MONTO NUMBER(8) NOT NULL CHECK(monto > 0));

CREATE TABLE PAGO (NPRESTAMO NUMBER(5) NOT NULL,NPAGO NUMBER(2) NOT NULL,CANTIDAD NUMBER(8) CHECK (CANTIDAD >0),F_VENC DATE NOT NULL,F_PAGO DATE,CONSTRAINT PKCUOTA PRIMARY KEY (NPRESTAMO,NPAGO),CONSTRAINT FKCUOTA_PRESTAMO FOREIGN KEY (NPRESTAMO) REFERENCES PRESTAMO(NPRESTAMO));

 

En la creación de las tablas se incluyeron todas las restricciones, excepto aquella que dice que toda cuota debe ser pagada antes de su fecha de vencimiento. A continuación se presenta el diseño del disparador que garantiza el cumplimiento de esta restricción:

Sentencia Disparadora: Como en la BD están todas los pagos (realizados o no) asociadas a los préstamos, la fecha de pago se actualiza. Por lo tanto, la sentencia disparadora es la actualización de fecha de pago en la tabla Pagos.

Antes / Después: La restricción de integridad no se puede violar, por lo tanto el trigger debe ser disparado antes de realizar la actualización.

Para Todas/Para el bloque: La verificación de la restricción se hace para todas las filas que se actualicen al ejecutar la sentencia disparadora.

Restrictor: Se debe impedir la actualización, sólo cuando la fecha de pago sea mayor que la fecha de vencimiento de la cuota.

Acción: Dar un error por violación de la restricción.

Page 21: Manual de Oracle 10g

Manual de Oracle

A continuación se especifica el trigger asociado con la tabla Pago:

CREATE OR REPLACE TRIGGER DIS_PAGOBEFORE UPDATE OF f_pago ON PagoFOR EACH ROWWHEN (new.f_pago > old.f_venc)BEGINraise_application_error(-20000, 'Pago ' || TO_CHAR(:old.nPago) || ' del prestamo ' || TO_CHAR(:old.nPrestamo) || ' vencida. Por favor, dirigirse a la gerencia.');END;

Para probar la validación del trigger insertaremos información en las tablas:

Insert into Deudor(ife,nombre,direccion,telefono) values ('1234567890123','alets lora','Nomeolvides 210','000000'); 

Insert into prestamo(nprestamo,ife,monto,interes)values (1234,'1234567890123',130000,1.26);

Insert into Pago (nprestamo,npago,cantidad,f_venc)values(1234,1,10000 + 10000 * 0.0126,'2(11/2013');

--Este update viola la integridad protegida por el trigger en donde la fecha de pago no --Puede ser superior a la fecha de vencimiento.Update Pago set f_pago = '05/11/2013' where nprestamo=1234 and npago=1;

select * from pago;

--Este update se ejecuta con exitoUpdate Pago set f_pago = '01/11/2013' where nprestamo=1234 and npago=1;

Los disparadores sea activan al crearlos.

Eliminar un disparador: DROP TRIGGER nombre_disparador;

Activar/ Desactivar dispadores: Existen dos opciones.

ALTER TRIGGER nombre_disparador {DISABLE | ENABLE};

ALTER TABLE nombre_tabla {ENABLE | DISABLE} ALL TRIGGERS;

Temporalidad del Evento: AFTER / BEFORE

Page 22: Manual de Oracle 10g

Manual de Oracle• BEFORE: Ejecutan la acción asociada antes de que la sentencia sea ejecutada– Decidir si la acción debe realizarse o no

– Utilizar valores alternativos para la sentencia

CREATE TRIGGER NombreTriggerBEFORE Insert ON NombreTabla ….

 

• AFTER: Ejecutan la acción asociada después de que se haya ejecutado la sentencia

CREATE TRIGGER NombreTriggerAFTER Insert ON NombreTabla ….

• INSTEAD OF: Desde Oracle 8 se proporciona los disparadores de sustitución, con ciertas restricciones

INSTEAD OF es una cláusula válida solo para vistas; no se puede especificar un disparador INSTEAD OF en una tabla.

Si una vista tiene un disparador INSTEAD OF, cualquier vista creada sobre ésta debe tener a su vez un disparador INSTEAD OF.

Cuando definimos disparadores INSTEAD OF para columnas LOB, podemos leer tanto el seudo-registro :OLD como el seudo-registro :NEW, pero no se puede modificar sus valores.

Evento: Tipo de orden DML sobre una tabla que provoca la activación del disparador.

{INSERT | DELETE | UPDATE [OF <lista de columnas>]}

La lista de columnas sólo tiene sentido en el evento UPDATE.

Granuralidad del Evento:

• A NIVEL DE FILA: FOR EACH ROW:Ejecutan la acción asociada tantas veces como filas se vean afectadas por la sentencia que lo dispara. Si ninguna fila se ve afectada, no se dispara

• A NIVEL DE SENTENCIA: FOR EACK STATEMENT: Disparadores con nivel de orden. Es la opción por defecto. Ejecutan una única vez la acción asociada,

Page 23: Manual de Oracle 10g

Manual de Oracleindependientemente del número de filas que se vean afectadas por la sentencia (incluso si no hay filas afectadas).

Condición: WHEN

La cláusula WHEN sólo es válida para los disparadores con nivel de fila, no puede contener subconsultas, vistas. Si está presente, el cuerpo del disparador sólo se ejecutará para las filas que cumplan la condición especificada en la cláusula.

La cláusula WHEN tiene la forma:

WHEN condición

donde condición es una expresión booleana que será evaluada para cada fila. Se puede hacer también referencia a los registros :new y :old dentro de la condición, pero en ese caso no se utilizan los dos puntos.

Registros :old y :new

Estas variables se utilizan del mismo modo que cualquier otra variable PL/SQL, con la salvedad de que no es necesario declararlas, son de tipo %ROWTYPE y contienen una copia del registro antes (OLD) y despues(NEW) de la acción SQL (INSERT, UPDATE, DELETE) que ha ejecutado el trigger. Utilizando esta variable podemos acceder a los datos que se están insertando, actualizando  o borrando.

 

De uso exclusivo en los disparadores de nivel de fila, si se intenta hacer referencia a cualquiera de los dos dentro de otro tipo de disparador, se obtendrá un error de compilación.

• :old y :new son registros que nos permiten acceder a los datos de la fila actual

La siguiente tabla resume los valores regresados por estos seudoregistros en diferentes eventos

EventoSeudoregistros

:OLD :NEW

INSERT NULL Nuevos valores

DELETE Valores almacenados NULL

Page 24: Manual de Oracle 10g

Manual de Oracle

UPDATE Valores almacenados Nuevos valores

 

Bloque PL/SQL

Bloque es la unidad de estructura básica en los programas PL/SQL. Supone una mejora en el rendimiento, pues se envían los bloques completos al servidor para ser procesados en lugar de enviar cada secuencia SQL.

Partes de un bloque:

Zona de declaraciones: zona opcional. Se declaran los objetos locales (variables, constantes...).

Zona de instrucciones: zona obligatoria. Zona de tratamiento de excepciones: zona opcional. Se tratan excepciones en el

programa.

 

Forma de crear un bloque:

Zona de declaraciones: DECLARE

Tipos de datos

NUMBERCHAR (longitud fija)VARCHAR (longitud variable)DATEBOOLEAN (es un tipo PL/SQL, no de BD).

Declaración implícita del tipo de datos.

var1 var2%TYPEvar tabla.campo%TYPE

Declaración de registros

var tabla%ROWTYPE

Page 25: Manual de Oracle 10g

Manual de Oraclevar cursor%ROWTYPE

 

Cuerpo: bloque PL/SQL y SQL, este bloque de instrucciones se realiza si se ejecuta la sentencia activadora especificada para el trigger y, si existe una cláusula WHEN ésta es TRUE. Con las siguientes restricciones:

Un disparador no puede emitir ninguna orden de control de transacciones (COMMIT, ROLLBACK o SAVEPOINT). El disparador se activa como parte de la ejecución de la orden que provocó el disparo, y forma parte de la misma transacción que dicha orden. Cuando la orden que provoca el disparo es confirmada o cancelada, se confirma o cancela también el trabajo realizado por el disparador.

Ningún procedimiento o función llamada por el disparador puede emitir órdenes de control de transacciones.

No puede contener ninguna declaración de variables LONG o LONG RAW. Restricciones en tablas a las que se puede acceder (Tablas Mutantes). No puede modificar las columnas de clave primaria.

 

INSERTING, DELETING Y UPDATING

Si un trigger puede ser activado por más de un tipo de operación (por ejemplo, "INSERT OR DELETE OR UPDATE OF Tabla"), el cuerpo del trigger puede utilizar los predicados condicionales INSERTING, DELETING y UPDATING para ejecutar bloques específicos de código, dependiendo del tipo de operación que activó el disparador.

La sintaxis es la siguiente

CREATE OR REPLACE TRIGGER EjemploBEFORE INSERT OR UPDATE OR DELETE ON tablaBEGIN IF DELETING THENAcciones asociadas al borradoELSIF INSERTING THENAcciones asociadas a la inserciónELSIF UPDATINGAcciones asociadas a la modificación END IF;END Ejemplo;

Page 26: Manual de Oracle 10g

Manual de OracleEn un UPDATE, se puede especificar el nombre de una columna en un predicado condicional UPDATING para determinar si la columna especificada ha sido actualizada. Por ejemplo:

CREATE OR REPLACE TRIGGER EjemploBEFORE INSERT OR DELETE OR UPDATE ON tablaBEGINIF DELETING THENAcciones asociadas al borradoELSIF INSERTING THENAcciones asociadas a la inserciónELSIF UPDATING(‘COL1’)Acciones asociadas a la modificaciónELSIF UPDATING(‘COL2’)Acciones asociadas a la modificaciónEND IF;

 

RAISE_APPLICATION_ERROR

Permite que un programa PL/SQL pueda generar errores tal y como lo hace Oracle.

Cuando se produce un error no tratado en la sección EXCEPTION, el error pasa fuera del bloque, al entorno que realizó la llamada.

Con RAISE_APPLICATION_ERROR se pueden generar errores similares con el mensaje que se quiera y, como ocurre con los errores generados por Oracle, el programa genera una EXCEPCIÓN.

La excepción puede tratarse en la sección EXCEPTION del bloque PL/SQL que la genera o del bloque que efectúe su llamada, usando el manejador OTHERS y SQLCODE/SQLERRM.

Formato: RAISE_APPLICATION_ERROR(<NE>, <ME>, [<PE>])o <NE>: Número del error, comprendido entre –20.000 y –20.999.o <ME>: Mensaje del error, de longitud máxima 512 caracteres.o <PE>: Preservar errores es un valor lógico opcional. Indica si el error se

introduce a la lista de errores ya generados (TRUE) o sustituye la lista actual con el nuevo error (FALSE, valor predeterminado).

Permite generar errores con mensajes más significativos que los que generaría Oracle: Puede utilizarse en la sección EXCEPTION.

Hace que requieran el mismo tratamiento los errores definidos por el usuario y los errores predefinidos.

Page 27: Manual de Oracle 10g

Manual de OracleHay Excepciones Predefinidas que controlan errores particulares (excepto OTHERS - Todas aquellas excepciones que no son controladas por el sistema manejador excepciones Oracle y/o por las excepciones definidas por el programador, controlando cualquier tipo de error). Algunas son:

INVALID_CURSOR: Se genera al intentar efectuar una operación ilegal sobre un cursor, como cerrar o intentar extraer datos de un cursor no abierto.

CURSOR_ALREADY_OPEN: Surge al intentar abrir un cursor ya abierto. NO_DATA_FOUND: Cuando una orden SELECT..INTO no devuelve ninguna fila

o cuando se intenta referenciar un elemento de una tabla PL/SQL al que no se le ha asignado ningún valor previamente.

TOO_MANY_ROWS: Si una orden SELECT..INTO devuelve más de una fila. INVALID_NUMBER: Si falla la conversión de cierto valor a un tipo NUMBER o

cuando usamos un dato no numérico en lugar de un dato numérico. VALUE_ERROR: Se genera cada vez que se produce un error aritmético, de

conversión, de truncamiento o de restricciones en una orden procedimental (si es una orden SQL se produce la excepción INVALID_NUMBER). Ej.: Si asignamos una cadena o número de mayor longitud que el tipo de la variable receptora.

STORAGE_ERROR y PROGRAM_ERROR: Son errores internos que no deberían producirse. Ocurren respectivamente si PL/SQL se queda sin memoria o por un fallo en el motor PL/SQL de Oracle y debería avisarse del error al departamento de soporte técnico de Oracle.

DUP_VAL_ON_INDEX: Es el error ORA-1, generado cuando se intenta insertar una fila en una tabla con un atributo UNIQUE y el valor de ese campo en la fila que se intenta insertar ya existe.

ZERO_DIVIDE: Intento de división por cero.

Ejemplos:

Se desea mantener la información de los socios del videoClub Patito, aunque estos se den de baja, para lo que se crea una tabla SOCIO_BAJA, que contiene los datos de socio y la fecha de baja y que se actualizará cada vez que se borre un socio.

Considere el siguiente código:

CREATE TABLE SOCIO(IFE CHAR(13) NOT NULL,nombreSocio CHAR(40) NOT NULL,direccion CHAR(50) NOT NULL,telefono CHAR(13) NOT NULL,

Page 28: Manual de Oracle 10g

Manual de OracleCONSTRAINT PK_SOCIOBAJA PRIMARY KEY (IFE));

CREATE TABLE SOCIO_BAJA (IFE CHAR(13) NOT NULL, nombreSocio CHAR(40) NOT NULL, direccion CHAR(50) NOT NULL, telefono CHAR(13) NOT NULL,FECHA_BAJA DATE,CONSTRAINT PK_BAJA PRIMARY KEY (IFE));

Disparador

CREATE OR REPLACE TRIGGER DIS_SOCIOAFTER DELETE ON SOCIOFOR EACH ROWBEGININSERT INTO Socio_Baja VALUES (:OLD.IFE, :OLD.nombreSocio, :OLD.direccion, :OLD.telefono, SYSDATE);END;

Ejemplo 

De la tabla empleado considere que el máximo salario posible es de $30,000 y el mínimo de $3,000 mensuales. Cualquier valor fuera de este rango deberá ajustarse a estos límites.

EMPLEADO

CREATE TABLE EMPLEADO(IDEMPLEADO NUMBER(3) NOT NULL,RFC CHAR(14), NOMBREEMPLEADO CHAR(40) NOT NULL, OFICIO CHAR(11) NOT NULL, CARGO CHAR(9) NOT NULL,JEFE NUMBER(3), INGRESO DATE NOT NULL, SALARIO NUMBER(10,2), COMISION NUMBER(10,2), CONSTRAINT DOM_EMPLEADO_SALARIO CHECK ( salario > 0 ),

Page 29: Manual de Oracle 10g

Manual de OracleCONSTRAINT PK_EMPLEADO PRIMARY KEY (idEmpleado), CONSTRAINT AK_EMPLEADO UNIQUE (rfc),CONSTRAINT FK_EMPLEADO_JEFE FOREIGN KEY (jefe) REFERENCES Empleado(IDEMPLEADO),CONSTRAINT DOM_EMPLEADO_NOMBREEMPLEADO CHECK (nombreEmpleado = NLS_UPPER(nombreEmpleado)));

DISPARADOR

CREATE OR REPLACE TRIGGER DIS_EMPLEADOBefore INSERT OR UPDATE OF SALARIO ON EMPLEADOFOR EACH ROWWHEN ((new.salario < 3000) OR (new.salario > 30000))BEGIN IF (:new.salario < 3000) THEN :new.salario := 3000; END IF; IF (:new.salario > 30000) THEN :new.salario := 30000; END IF;END;

 

Compilado Triggers

El funcionamiento de un trigger deja de estar ENABLE si dependen de Procedimientos almacenados o función en el cuerpo del disparador y este es modificado. Los disparadores DISABLE por razones de dependencia son recompilado en la próxima invocación.

Es posible que pueda examinar las ALL_DEPENDENCIES para ver las dependencias de un disparador. Por ejemplo, la siguiente declaración

SELECT NAME, REFERENCED_OWNER, REFERENCED_NAME, REFERENCED_TYPE FROM ALL_DEPENDENCIESWHERE OWNER = 'EPACHECO'

Creación de atributos autoincrement en Oracle

En muchos casos es útil poseer campos autoincrementales en una base de datos. Algunos gestores de bases de datos permiten hacer esto de forma automática mediante

Page 30: Manual de Oracle 10g

Manual de OracleAUTOINCREMENT, IDENTITY, etc. pero Oracle no posee esta característica. A continuación se mostrará cómo hacerlo para crear un campo numérico que incremente su valor automáticamente.Vamos a crear una tabla a modo de ejemplo llamada usuarios la cual va a almacenar cierta información. Esta tabla tendrá una clave primaria (idUsr) la cual será autoincrementada automáticamente.Creación de tabla usuarios

CREATE TABLE Usuario(

  idUsr NUMBER PRIMARY KEY,

  NomUsrVARCHAR2(60) NOT NULL,

  DomUsrVARCHAR(60),

  FecNac DATE

);

Como podemos comprobar, la creación de la tabla usuario no tiene ningún elemento diferenciador ni hay ningún indicio que va a contener un campo auto numérico.

Creación de la secuencia

Para simular esta funcionalidad en Oracle debemos crear una secuencia, la cual poseerá las siguientes características básicas:

nombre valor de inicio valor de fin (valor máximo) incremento.

CREATE SEQUENCE seq_usuarios_idusuario --nombre de la secuencia

START WITH 1 --la secuencia empieza por 1

INCREMENT BY 1 --se incrementa de uno en uno

NOMAXVALUE; --no tiene valor maximo

Con la secuencia creada, podemos obtener su valor actual llamando a la función nextval indicando nombreDeSecuencia.nextval.

SELECT seq_usuarios_idusuario.nextval FROM dual;

Con este select obtenemos un nuevo valor de la secuencia. Una vez que ésta da un valor, no lo volverá a ofrecer más. Si queremos consultar el valor por el que se encuentra actualmente la secuencia, lo podemos hacer mediante currval.

Page 31: Manual de Oracle 10g

Manual de Oracle

SELECT seq_usuarios_idusuario.currval FROM dual;

Ya tenemos la secuencia que genera números de forma continua, ahora necesitamos algún método para añadir estos valores a la clave primaria de la tabla creada anteriormente. Es cierto que siempre podemos usar nextval en un insert de forma:

INSERT INTO usuario(idUsr, NomUsr)

VALUES(seq_usuarios_idusuario.nextval, ‘Juan Perez’);

Pero quizá sea mejor buscar una forma automática de hacer esta inserción. Para ello, usaremos un disparador o trigger.

Creación del disparador

Para que este proceso se realice automáticamente debemos crear un disparador tal y como vemos a continuación.

CREATE TRIGGER trig_usuarios_seq

BEFORE INSERT ON usuario

FOR EACH ROW

BEGIN

SELECT seq_usuarios_idusuario.nextval INTO :new.idUSR FROM dual;

END

;

El cual, antes de realizar cualquier inserción en la tabla usuarios, asignará el nextval de nuestra secuencia al nuevo valor del campo id, con lo cual, posteriormente, se realizará el insert con el id generado automáticamente. De esta forma, en el insert anterior, podemos obviar la inserción de la clave primaria sin obtener ningún error.