Archivo

Archivo del autor

PL/SQL – Paquetes ORACLE

Uno de los elementos más importantes son los paquetes («packages»). En general, es recomendable empaquetar el código PL/SQL, evitando el uso de funciones y procedimientos aislados.

Aqui las principales ventajas que propociona el uso de paquetes :

• Agrupa elementos relacionados, haciéndolos mucho más manejables.
• Define una parte pública (especificación) y otra privada (variables, funciones y procedimientos del cuerpo que no se han indicado en la especificación); ocultando complejidad, abstrayendo al desarrollador que lo usa de los detalles innecesarios, e incorporando seguridad.
• Las variables a nivel de paquete, son persistentes durante cada sesión (sólo para dicha sesión); incluso cuando el código que las usa termina su ejecución. Por tanto, podemos declarar una variable en la especificación de un paquete; de modo que un usuario autorizado se conecte y consulte su valor desde un procedimiento; y en la misma sesión, ejecute otro procedimiento que consulte la misma variable, observando el valor que quedó anteriormente, y pudiendo cambiarlo, claro. Dicho valor no lo verán otras sesiones.
• Un paquete, en su implementación, además de variables, funciones y procedimientos, puede incluir un cuerpo (begin … exception … end), que sirva como código de inicialilzación del mismo (interesante para asignar un valor inicial a las variables del paquete). Es recomendable incluir dicho código en un procedimiento privado del paquete (por ejemplo llamado «inicializar«), y llamarlo en el cuerpo; facilitando así la depuración de errores.

El único caso en que puede suponer un problema usar paquetes, es cuando tenemos una función/procedimiento cuya lógica no cambia, que se usa en muchas partes de mi aplicación y, está ubicada dentro de un paquete que contiene otros elementos cuya lógica cambia con frecuencia. Esto hace que cada cambio en la implementación del paquete suponga recompilar todos aquellos elementos de mi aplicación que usan la función (aunque el cuerpo de la misma realmente no haya cambiado).

Para evitar ésto:

• Aislaremos y separaremos aquellas funcionalidades que raramente sufran cambios, de aquellas partes de mi aplicación que se modifiquen con frecuencia. Esto lo podemos hacer con un conjunto pequeño de funciones/procedimientos aislados (no empaquetados), o con un paquete que los agrupe.
• Si nuestros paquetes incluyen constantes en la especificación, que pueden cambiar con cierta frecuencia, y queremos evitar recompilaciones de los paquetes que las usan, podemos sustituir cada constante por una función que nos devuelva el valor.

El siguiente fragmento de código se muestra la creacion de un package con un unico procedimiento. Puede tener muchas variables globales definidas y múltiples procedimientos o funciones dentro de un paquete.

CREATE PACKAGE CLIENTES_SALARIO AS
PROCEDURE BUSCAR_SALARIO(c_id CLIENTES.ID%type);
END CLIENTES_SALARIO;
/

Package Body – Cuerpo del paquete

CREATE OR REPLACE PACKAGE BODY CLIENTES_SALARIO AS
PROCEDURE BUSCAR_SALARIO(c_id CLIENTES.ID%TYPE) IS
c_sal CLIENTES.SALARIO%TYPE;
BEGIN
SELECT SALARIO INTO c_sal
FROM CLIENTES
WHERE ID = c_id;
dbms_output.put_line(‘SALARIO: ‘|| c_sal);
END BUSCAR_SALARIO;
END CLIENTES_SALARIO;
/

Paquetes001

Utilizando los elementos del paquete :
Los elementos del paquete (variables, procedimientos o funciones) se accede con la siguiente sintaxis:

Paquetes002

SET SERVEROUTPUT ON SIZE 1000000;
DECLARE
code CLIENTES.ID%type := &cc_id;
BEGIN
CLIENTES_SALARIO.BUSCAR_SALARIO(code);
END;
/

Paquetes003

 

Ejemplo:
El siguiente programa ofrece un paquete más completo. Usaremos la tabla CLIENTES almacenada en nuestra base de datos con los siguientes registros:

Paquetes004

Creamos el siguiente paquete :

CREATE OR REPLACE PACKAGE CLIENTES_Package AS

— Agregar Cliente
PROCEDURE NuevoCliente(c_id   CLIENTES.ID%type,
c_nombre     CLIENTES.NOMBRE%type,
c_edad       CLIENTES.EDAD%type,
c_direccion  CLIENTES.DIRECCION%type,
c_salario    CLIENTES.SALARIO%type);

   — Eliminar Cliente
PROCEDURE EliminarCliente(c_id  CLIENTES.ID%TYPE);

   — Listar Cliente
PROCEDURE ListarClientes;

END CLIENTES_Package;
/

Paquetes005

CREACIÓN DEL CUERPO DEL PAQUETE:

CREATE OR REPLACE PACKAGE BODY CLIENTES_Package AS
PROCEDURE NuevoCliente(c_id  CLIENTES.ID%type,
c_nombre     CLIENTES.NOMBRE%type,
c_edad       CLIENTES.EDAD%type,
c_direccion  CLIENTES.DIRECCION%type,
c_salario    CLIENTES.SALARIO%type)
   IS
   BEGIN
      INSERT INTO CLIENTES (ID,NOMBRE,EDAD,DIRECCION,SALARIO)
VALUES(c_id, c_nombre, c_edad, c_direccion, c_salario);
END NuevoCliente;

PROCEDURE EliminarCliente(c_id   CLIENTES.ID%type) IS
   BEGIN
       DELETE FROM CLIENTES
         WHERE ID = c_id;
END EliminarCliente;

PROCEDURE ListarClientes IS

CURSOR c_Clientes IS
SELECT NOMBRE FROM CLIENTES;

TYPE c_List IS TABLE OF CLIENTES.NOMBRE%type;
lista_nombres c_List := c_List();

contador integer :=0;
BEGIN
      FOR n IN c_Clientes LOOP
contador := contador +1;
lista_nombres.extend;
lista_nombres(contador)  := n.nombre;
dbms_output.put_line(‘Cliente (‘ ||contador|| ‘)’||lista_nombres(contador));
     END LOOP;
END ListarClientes;

END CLIENTES_Package;
/

Paquetes006

USO DEL PAQUETE:
El siguiente programa utiliza los métodos declarados y definidos en CLIENTES_Package

DECLARE
code CLIENTES.ID%type:= 8;
BEGIN
CLIENTES_Package.NuevoCliente(7, ‘Liliana‘, 25, ‘Aquino‘, 3500);
CLIENTES_Package.NuevoCliente(8, ‘Victor‘, 32, ‘Huaman‘, 7500);
CLIENTES_Package.ListarClientes ;
CLIENTES_Package.EliminarCliente(code);
CLIENTES_Package.ListarClientes ;
END;
/

Paquetes007

logo shipment4you 342 68 PNG ESP WEB

Categorías: Oracle

PL/SQL – Exceptions

Un error durante la ejecución de un programa llama a una excepción en PL/SQL. PL/SQL soporta atrapar las excepción en el programa y tomar una acción apropiada desacuerdo a la condición de error.

Hay dos tipos de excepciones:

Excepciones definidas por el sistema
Excepciones definidas por el usuario

En el siguiente ejemplo muestro el uso de los tipos de excepciones :

DECLARE
c_id               CLIENTES.ID%type := &cc_id;
c_nombre    CLIENTES.NOMBRE%type;
c_direccion CLIENTES.DIRECCION%type;

— Excepcion definida por el usuario
ex_invalid_id  EXCEPTION;

BEGIN
IF c_id <= 0 THEN
RAISE ex_invalid_id; — Excepcion definida por el usuario
   ELSE
      SELECT  nombre, direccion INTO  c_nombre, c_direccion
FROM Clientes
WHERE id = c_id;

DBMS_OUTPUT.PUT_LINE (‘Nombre: ‘||  c_nombre);
DBMS_OUTPUT.PUT_LINE (‘Direccion: ‘ || c_direccion);

   END IF;
EXCEPTION
   WHEN ex_invalid_id THEN
dbms_output.put_line(‘ID debe ser mayor que cero!’);
WHEN no_data_found THEN
dbms_output.put_line(‘No existe el cliente!’);
WHEN OTHERS THEN
dbms_output.put_line(‘Error!’);
END;
/

Creacion Tabla Clientes para que puedas probar el codigo.

Excepcion

Se ejecuta …

SQLCODE

ACCESS_INTO_NULL El programa intentó asignar valores a los atributos de un objeto no inicializado -6530
COLLECTION_IS_NULL El programa intentó asignar valores a una tabla anidada aún no inicializada -6531
CURSOR_ALREADY_OPEN El programa intentó abrir un cursor que ya se encontraba abierto. Recuerde que un cursor de ciclo FOR automáticamente lo abre y ello no se debe especificar con la sentencia OPEN -6511
DUP_VAL_ON_INDEX El programa intentó almacenar valores duplicados en una columna que se mantiene con restricción de integridad de un índice único (unique index) -1
INVALID_CURSOR El programa intentó efectuar una operación no válida sobre un cursor -1001
INVALID_NUMBER En una sentencia SQL, la conversión de una cadena de caracteres hacia un número falla cuando esa cadena no representa un número válido -1722
LOGIN_DENIED El programa intentó conectarse a Oracle con un nombre de usuario o password inválido -1017
NO_DATA_FOUND Una sentencia SELECT INTO no devolvió valores o el programa referenció un elemento no inicializado en una tabla indexada 100
NOT_LOGGED_ON El programa efectuó una llamada a Oracle sin estar conectado -1012
PROGRAM_ERROR PL/SQL tiene un problema interno -6501
ROWTYPE_MISMATCH Los elementos de una asignación (el valor a asignar y la variable que lo contendrá) tienen tipos incompatibles. También se presenta este error cuando un parámetro pasado a un subprograma no es del tipo esperado -6504
SELF_IS_NULL El parámetro SELF (el primero que es pasado a un método MEMBER) es nulo -30625
STORAGE_ERROR La memoria se terminó o está corrupta -6500
SUBSCRIPT_BEYOND_COUNT El programa está tratando de referenciar un elemento de un arreglo indexado que se encuentra en una posición más grande que el número real de elementos de la colección -6533
SUBSCRIPT_OUTSIDE_LIMIT El programa está referenciando un elemento de un arreglo utilizando un número fuera del rango permitido (por ejemplo, el elemento “-1”) -6532
SYS_INVALID_ROWID La conversión de una cadena de caracteres hacia un tipo rowid falló porque la cadena no representa un número -1410
TIMEOUT_ON_RESOURCE Se excedió el tiempo máximo de espera por un recurso en Oracle -51
TOO_MANY_ROWS Una sentencia SELECT INTO devuelve más de una fila -1422
VALUE_ERROR Ocurrió un error aritmético, de conversión o truncamiento. Por ejemplo, sucede cuando se intenta calzar un valor muy grande dentro de una variable más pequeña -6502
ZERO_DIVIDE El programa intentó efectuar una división por cero -1476

logo shipment4you 342 68 PNG ESP WEB

Categorías: Oracle

PL/SQL – Variables de tipo Registros

PL / SQL Un registro es una estructura de datos que puede contener elementos de datos de diferentes tipos. Los registros consisten en diferentes campos , de forma similar a una fila de una tabla de base de datos.

Creamos una tabla clientes :
CREATE TABLE CLIENTES(
ID                INT NOT NULL,
Nombre     VARCHAR (20) NOT NULL,
Edad           INT NOT NULL,
Direccion  CHAR (25),
Salario       DECIMAL (18, 2),
   PRIMARY KEY (ID)
);
INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (1, ‘Ricardo’, 32, ‘Huaman’, 2000.00 );INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (2, ‘Juan’, 25, ‘Avila’, 1500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (3, ‘Aldo’, 23, ‘Laderas’, 2000.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (4, ‘Victor’, 25, ‘Moreno’, 6500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (5, ‘Miguel’, 27, ‘Huaman’, 8500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (6, ‘Carlos’, 22, ‘Campos’, 4500.00 );

Registros Basados en Tabla – El atributo %ROWTYPE permite a un programador crear variables basadosen tablas.

DECLARE
Clientes_Reg Clientes%rowtype;
BEGIN
   SELECT * INTO Clientes_Reg
FROM Clientes
WHERE id = 5;
dbms_output.put_line(‘Cliente ID: ‘ || Clientes_Reg.ID);
dbms_output.put_line(‘Cliente Nombre: ‘ || Clientes_Reg.NOMBRE);
dbms_output.put_line(‘Cliente Direccion: ‘ || Clientes_Reg.DIRECCION);
dbms_output.put_line(‘Cliente Salario: ‘ || Clientes_Reg.SALARIO);
END;
/

VarRegistro001

Cursor Basado en Registros – El siguiente ejemplo muestra el concepto de cursores basados en registros. Nosotros vamos a usar la tabla CLIENTES que habíamos creado anteriormente :

DECLARE
   CURSOR Clientes_Cursor is
SELECT id, Nombre, Direccion
FROM Clientes;
Clientes_Reg Clientes_Cursor%rowtype;
BEGIN
   OPEN Clientes_Cursor;
LOOP
FETCH Clientes_Cursor INTO Clientes_Reg;
      EXIT WHEN Clientes_Cursor%notfound;
DBMS_OUTPUT.put_line(Clientes_Reg.id || ‘ ‘ || Clientes_Reg.Nombre);
   END LOOP;
END;
/

VarRegistro002

PL/SQL proporciona un tipo de registro definido por el usuario que le permite definir diferentes estructuras de registro . Los registros consisten en diferentes campos. Supongamos que desea realizar un seguimiento de sus libros en una biblioteca. Es posible que desee realizar un seguimiento de los siguientes atributos acerca de cada libro :

DECLARE
type Libros is record
(Titulo varchar(50),
Autor varchar(50),
Asunto varchar(100),
ID number);
Libro1 Libros;
Libro2 Libros;
BEGIN

   — Primer Libro
Libro1.Titulo  := ‘Pl/Sql’;
Libro1.Autor := ‘Nuha Ali ‘;
Libro1.Asunto := ‘C Programming Tutorial’;
Libro1.ID := 6495407;

   — Segundo Libro
Libro2.Titulo := ‘SQL Server 2014’;
Libro2.Autor := ‘Zara Ali’;
Libro2.Asunto := ‘Telecom Billing Tutorial’;
Libro2.ID := 6495700;

   — Imprimir el primer registro
dbms_output.put_line(‘Libro 1 Titulo : ‘|| Libro1.Titulo);
dbms_output.put_line(‘Libro 1 author : ‘|| Libro1.Autor);
dbms_output.put_line(‘Libro 1 subject : ‘|| Libro1.Asunto);
dbms_output.put_line(‘Libro 1 book_id : ‘ || Libro1.ID);

   — Imprimir el segundo registro
dbms_output.put_line(‘Libro 2 Titulo : ‘|| Libro2.Titulo);
dbms_output.put_line(‘Libro 2 author : ‘|| Libro2.Autor);
dbms_output.put_line(‘Libro 2 subject : ‘|| Libro2.Asunto);
dbms_output.put_line(‘Libro 2 book_id : ‘ || Libro2.ID);

END;
/

Variables 003

Puede pasar un registro como parámetro a un subprograma en forma muy similar a como se pasa cualquier otra variable . Se podría acceder a los campos de forma similar a la que ha accedido en el ejemplo anterior :

DECLARE
   TYPE Libros is record
(Titulo varchar(50),
Autor varchar(50),
Asunto varchar(100),
ID number);
Libro1 Libros;
Libro2 Libros;

PROCEDURE imprimirbook (Libro Libros) IS
BEGIN
dbms_output.put_line(‘Libro Titulo : ‘|| Libro.Titulo);
dbms_output.put_line(‘Libro Author : ‘|| Libro.Autor);
dbms_output.put_line(‘Libro Asunto : ‘|| Libro.Asunto);
dbms_output.put_line(‘Libro ID : ‘ || Libro.ID);
dbms_output.put_line(RPAD(‘-‘, 50, ‘-‘));
END;

BEGIN
   — Primer Libro
Libro1.Titulo  := ‘Pl/Sql’;
Libro1.Autor := ‘Nuha Ali ‘;
Libro1.Asunto := ‘C Programming Tutorial’;
Libro1.ID := 6495407;

   — Segundo Libro
Libro2.Titulo := ‘SQL Server 2014’;
Libro2.Autor := ‘Zara Ali’;
Libro2.Asunto := ‘Telecom Billing Tutorial’;
Libro2.ID := 6495700;

   — Imprimir
imprimirbook (Libro1);
imprimirbook (Libro2);

END;
/

 

logo shipment4you 342 68 PNG ESP WEB

Categorías: Oracle

PL / SQL Declaración de constantes:

Constantes

En este ejemplo , vamos a guardar el PI que es constante número real , el radio y el área que son números reales ,

DECLARE
PI                  CONSTANT REAL := 3.14159;
Radio           REAL := 3;
Area             REAL := (PI * Radio**2);
BEGIN
dbms_output.put_line(‘ PI: ‘ || PI );
dbms_output.put_line(‘ Radio: ‘ || Radio);
dbms_output.put_line(‘ Area: ‘ || Area);
END;
/

logo shipment4you 342 68 PNG ESP WEB

Categorías: Oracle

Sintaxis de declaración de variables

La sintaxis general de declarar una variable es :
nombre_variable TipoDato[Size] [NOT NULL] := [ value ];
  1. nombre_variable es el nombre predefinido de la variable.
  2. El tipo de datos es un tipo de datos PL / SQL válida .
  3. El tamaño es una especificación opcional del tamaño de tipo de datos para mantener el valor de tamaño máximo.
  4. NOT NULL es una especificación opcional del valor de la variable no se puede aceptar NULL .
  5. value es también una especificación opcional , donde se puede inicializar el valor de la variable. 6. Cada declaración de variable se termina con un punto y coma.

Variables 001

DECLARE
lnNumEmpleado number(5) NOT NULL := 2;           — NOT NULL ( valor no puede estar en blanco ) , Asignar valor inicial
lcNombreEmpleado varchar2(15) := ‘Branson Devs’; — intialize valor en el momento de la declaración
BEGIN
dbms_output.put_line(‘Declaracion de Valores:’);
dbms_output.put_line(‘Numero Empleados: ‘ || lnNumEmpleado || ‘ Nombre Empleado: ‘ || lcNombreEmpleado);
END;
/

Alcance de las Variables

PL / SQL identifica el rango de región que puede hacer referencia una variable. PL / SQL tiene dos tipos de ámbitos ámbito local y alcance global,

Las variables locales – Variables declaradas en el bloque interior y no pueden ser referenciados por los bloques externos.

Las variables globales – Son variables declaradas en un bloque exterior y puede estar haciendo referencia en los bloques interiores.

DECLARE
num1 number := 10;
num2 number := 20;
BEGIN
    DECLARE
num_adicional number;
BEGIN
num_adicional := num1 + num2;
dbms_output.put_line(‘La suma es: ‘ || num_adicional);
END— Fin de acceso a variables num_adicional
END;
/

Variables 002

Este ejemplo muestra una diferencia entre el bloque interior y bloque exterior para el alcance de una variable. Se puede utilizar la palabra clave OUTER accediendo a la variable de bloque exterior dentro del bloque interior .

DECLARE
num number := 11;
BEGIN
    DECLARE
num number := 10;
BEGIN
        IF num = outer.num THEN
DBMS_OUTPUT.PUT_LINE(‘Ambas variables tiene el mismo valor’);
ELSE
DBMS_OUTPUT.PUT_LINE(‘Diferentes valores’);
       END IF;
    END;  — Fin de alcance para la variable num
END;
/
Asignación de valores a variables PL/SQL desde una  consulta SQL
Creamos una tabla clientes
CREATE TABLE CLIENTES(
ID                INT NOT NULL,
Nombre     VARCHAR (20) NOT NULL,
Edad           INT NOT NULL,
Direccion  CHAR (25),
Salario       DECIMAL (18, 2),
   PRIMARY KEY (ID)
);
Le insertamos registros :
INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (1, ‘Ricardo’, 32, ‘Huaman’, 2000.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (2, ‘Juan’, 25, ‘Avila’, 1500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (3, ‘Aldo’, 23, ‘Laderas’, 2000.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (4, ‘Victor’, 25, ‘Moreno’, 6500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (5, ‘Miguel’, 27, ‘Huaman’, 8500.00 );

INSERT INTO Clientes (ID,nombre,edad,direccion,salario)
VALUES (6, ‘Carlos’, 22, ‘Campos’, 4500.00 );

El siguiente programa asigna valores de la tabla de arriba para las variables PL / SQL con la cláusula SELECT INTO de SQL:
Variables 003
DECLARE
c_id              CLIENTES.ID%type := 1;
c_nombre   CLIENTES.NOMBRE%type;
c_direcc      CLIENTES.DIRECCION%type;
c_salario     CLIENTES.SALARIO%type;
BEGIN
SELECT NOMBRE, DIRECCION, SALARIO INTO c_nombre, c_direcc, c_salario
FROM CLIENTES
WHERE id = c_id;
dbms_output.put_line(‘Cliente : ‘ ||c_nombre || ‘ de ‘ || c_direcc || ‘ con salario ‘ || c_salario);
END;
/
logo shipment4you 342 68 PNG ESP WEB
Categorías: Oracle

PL SQL – ¿Por qué anidar bloques?

Podemos poner BEGIN antes de cualquier conjunto de una o más sentencias ejecutables seguidas de un END, creando un bloque anidado con esas sentencias.

Existen 2 ventajas principales para hacer esto:

(1) posponer la asignación de memoria para variables que se necesitan únicamente en el bloque anidado, y

(2) limitar la propagación de una excepción lanzada por una de las sentencias del bloque anidado.

SET SERVEROUTPUT ON SIZE 1000000;
DECLARE
lcMensaje1  VARCHAR2(100) := ‘Hola’;
lcMensaje2  VARCHAR2(100) := ‘ RAHSUAREZ!’;
BEGIN
  IF SYSDATE >= TO_DATE(’01/01/2015′)
THEN
lcMensaje2 := lcMensaje1 || lcMensaje2;
DBMS_OUTPUT.put_line(lcMensaje2);
ELSE
DBMS_OUTPUT.put_line(lcMensaje1);
END IF;
END;

Bloques 001

El bloque despliega “¡Hola RAHSUAREZ!” cuando la fecha de hoy (retornada por SYSDATE) es por lo menos el primer día de 2015; en otro caso, únicamente despliega el mensaje “Hola”. Aunque este bloque se ejecute en 2011, asigna memoria para la variable lcMensaje2.

Si reestructuramos este bloque, la memoria para lcMensaje2 será asignada únicamente después del 2015:

DECLARE
lcMensaje1  VARCHAR2(100) := ‘Hola’;
BEGIN
   IF SYSDATE > TO_DATE(’01/01/2015′)
THEN
      DECLARE
lcMensaje2  VARCHAR2(100) := ‘ RAHSUAREZ!’;
BEGIN
lcMensaje2 := lcMensaje1 || lcMensaje2;
DBMS_OUTPUT.put_line(lcMensaje2);
END;
   ELSE
DBMS_OUTPUT.put_line(lcMensaje1);
   END IF;
END;

De forma similar, podemos agregar una sección de excepciones a este bloque anidado, atrapando errores y permitiendo que el bloque exterior continúe con su ejecución:

DECLARE
lcMensaje1  VARCHAR2(100) := ‘Hola’;
BEGIN
   IF SYSDATE > TO_DATE(’01/01/2015′)
   THEN
      DECLARE
lcMensaje2  VARCHAR2(100) := ‘ RAHSUAREZ!’;
BEGIN
lcMensaje2 := lcMensaje1 || lcMensaje2;
DBMS_OUTPUT.put_line(lcMensaje2);
      EXCEPTION
      WHEN OTHERS
      THEN
DBMS_OUTPUT.put_line(DBMS_UTILITY.format_error_stack);
      END;
   ELSE
DBMS_OUTPUT.put_line(lcMensaje1);
   END IF;
END;

Bloques 002

 

logo shipment4you 342 68 PNG ESP WEB

Categorías: Oracle

Ejecutando SQL dentro de bloques PL/SQL

PL/SQL es un lenguaje de programación de base de datos. Casi todos los programas que escribiremos en PL/SQL leerán desde, o escribirán en, una base de datos Oracle utilizando SQL. Aunque estas series asumen que se conoce SQL, debemos estar conscientes de la forma en que llamamos a las sentencias desde un bloque PL/SQL.

Oracle hace que sea muy fácil escribir y ejecutar sentencias SQL en PL/SQL. La mayor parte de las veces, simplemente escribiremos las sentencias SQL directamente en nuestro bloque PL/SQL y después agregaremos el código necesario para la interfaz entre las sentencias SQL y el código PL/SQL.

Supongamos, por ejemplo, que tenemos una tabla llamada ESTUDIANTES, con una columna clave primaria id, y una columna apellido. Podemos ver el apellido del empleado con ID 2, como sigue:

Ejecutando 001

DROP TABLE Estudiantes CASCADE CONSTRAINTS;
CREATE TABLE Estudiantes (
id                      NUMBER(5) PRIMARY KEY,
nombre           VARCHAR2(20),
apellido          VARCHAR2(20),
pension          FLOAT,
creditos         NUMBER(3)
);

DROP SEQUENCE Estudiantes_Secuencia;
CREATE SEQUENCE Estudiantes_Secuencia
  START WITH 10000
  INCREMENT BY 1;

INSERT INTO Estudiantes (id, nombre, apellido, pension, creditos)
VALUES (Estudiantes_Secuencia.NEXTVAL, ‘Ricardo’, ‘Huaman’, 100, 11);

INSERT INTO Estudiantes (id, nombre, apellido, pension, creditos)
VALUES (Estudiantes_Secuencia.NEXTVAL, ‘Juan’, ‘Victorio’,120, 11);

SELECT * FROM Estudiantes;

Ahora vamos a ejecutar esta una consulta dentro de nuestro bloque PL/SQL y desplegar el nombre. Para hacer esto, necesitaremos “copiar” el apellido desde la tabla a una variable local, lo cual podemos hacer con la cláusula INTO:

DECLARE
lcApellido Estudiantes.apellido%TYPE;
BEGIN

SELECT apellido
INTO lcApellido
FROM Estudiantes
WHERE id = 10000;

DBMS_OUTPUT.put_line(lcApellido);

END;

Ejecutando 002

Primero declaramos una variable local, y haciendo esto introducimos otra característica de PL/SQL: la capacidad de fijar el tipo de datos de nuestra variable en función del tipo de datos de una columna en una tabla

Después ejecutamos una consulta contra la base, obteniendo el apellido del estudiante y asignándolo directamente en la variable lcApellido.

Otro ejemplo ahora ejecutamos la sentencias SELECT en PL/SQL, también querremos insertar, modificar y eliminar datos desde PL/SQL. Aquí hay ejemplos de cada uno de esos tipos de sentencias DML:

• Eliminamos todos los estudiantes cuya pension es igual a 100 y mostramos cuántas tuplas fueron eliminadas:

Ejecutando 003

DECLARE
lnpension Estudiantes.pension%TYPE := 100;
BEGIN
  DELETE FROM Estudiantes
WHERE Pension = lnpension;

DBMS_OUTPUT.put_line(SQL%ROWCOUNT);
END;

SELECT * FROM Estudiantes;

logo shipment4you 342 68 PNG ESP WEB

 

Categorías: Oracle

Sobre los nombres en una base Oracle

Ahora que ya se aprecia la importancia de asignar nombres a la lógica, es tiempo de hablar sobre las reglas para los nombres (identificadores) tanto en PL/SQL como, de forma más general, en una base Oracle.

Estas son las reglas para construir identificadores válidos en una base Oracle:

• El largo máximo es de 30 caracteres.
• El primer caracter debe ser una letra, pero cada caracter después del primero puede ser una letra, un número (0 a 9), un signo de pesos ($), un guión bajo (_), o un numeral (#).

Ejemplos de identificadores válidos:

hola_RAHSUAREZ
hola$RAHSUAREZ
hola#RAHSUAREZ

pero estos son inválidos:
1hola_RAHSUAREZ
hola%RAHSUAREZ

• PL/SQL es case-insensitive (no es sensitivo a mayúsculas y minúsculas) con respecto a los identificadores. PL/SQL trata todos los siguientes como el mismo identificador:

hola_rahsuarez
Hola_Rahsuarez
HOLA_RAHSUAREZ

Para ofrecer más flexibilidad, Oracle permite evitar las restricciones de la segunda y tercera regla, encerrando al identificador entre comillas dobles. El identificador encerrado entre comillas puede contener cualquier secuencia de caracteres imprimibles excluyendo las comillas dobles; las diferencias entre mayúsculas y minúsculas serán además preservadas. Así, todos los siguientes identificadores son válidos y distintos:

«Abc»
«ABC»
«a b c»

Es muy raro encontrar identificadores entre comillas en código PL/SQL.

Estas mismas reglas aplican a los nombres de los objetos de base de datos como tablas, vistas y procedimientos, con una regla adicional: a menos que se encierren entre comillas los nombres de estos objetos, Oracle los mantendrá en mayúsculas. Ejemplo:

CREATE OR REPLACE PROCEDURE hola_rahsuarez IS
BEGIN
DBMS_OUTPUT.put_line(‘¡Hola RAHSUAREZ!’);
END hola_rahsuarez;

Leer más…

Categorías: Oracle

Construyendo con Bloques en PL/SQL

PL/SQL es un lenguaje estructurado con bloques. Un bloque PL/SQL es definido por las palabras clave :

DECLARE, BEGIN, EXCEPTION, y END

que dividen el bloque en tres secciones

1. Declarativa: sentencias que declaran variables, constantes y otros elementos de código, que después pueden ser usados dentro del bloque
2. Ejecutable: sentencias que se ejecutan cuando se ejecuta el bloque
3. Manejo de excepciones: una sección especialmente estructurada para atrapar y manejar cualquier excepción que se produzca durante la ejecución de la sección ejecutable

Sólo la sección ejecutable es obligatoria. No es necesario que usted declare nada en un bloque, ni que maneje las excepciones que se puedan lanzar.

SET SERVEROUTPUT ON
PL/SQL en Oracle requiere para obtener el resultado en pantalla SERVEROUTPUT .

Un bloque es en sí mismo una sentencia ejecutable, por lo que se pueden anidar los bloques unos dentro de otros.

Aquí hay algunos ejemplos:

El clásico “¡Hola RAHSUAREZ!” es un bloque con una sección ejecutable que llama al procedimiento DBMS_OUTPUT.PUT_LINE para mostrar texto en pantalla:

BEGIN
DBMS_OUTPUT.put_line(‘¡Hola RAHSUAREZ!‘);
END;

HOLA RAHSUAREZ

El siguiente bloque declara una variable de tipo VARCHAR2 (un string) con un largo máximo de 100 bytes para contener el string ‘¡Hola RAHSUAREZ!’.
Después, el procedimiento DBMS_OUTPUT.PUT_LINE acepta la variable, en lugar del literal, para desplegarlo:

DECLARE
lmensaje VARCHAR2(100) := ‘¡Hola RAHSUAREZ!’;
BEGIN
DBMS_OUTPUT.put_line(lmensaje);
END;

Leer más…

Categorías: Oracle

Create Sequence – Generador de indentificadores unicos que no bloquea transacciones

Crea un objeto capaz de darnos numeros consecutivos unicos.

CREATE SEQUENCE secuencia
INCREMENT BY n
START WITH n
{MAX VALUE n | NOMAXVALUE}
{MIN VALUE N | NOMINVALUE}
{CYCLE | NOCYCLE}
{CACHE N | NOCACHE}
{ORDER | NOORDER};

En realida es un generador de indentificadores unicos que no bloquea transacciones.
Es muy util para generar primary keys.

Oracle Incrementar

DROP TABLE students CASCADE CONSTRAINTS;

CREATE TABLE students (
id                       NUMBER(5) PRIMARY KEY,
first_name       VARCHAR2(20),
last_name        VARCHAR2(20),
major                VARCHAR2(30),
current_credits  NUMBER(3)
);

CREATE SEQUENCE student_sequence
START WITH 10000
INCREMENT BY 1;

INSERT INTO students (id, first_name, last_name, major,
current_credits)
VALUES (student_sequence.NEXTVAL, ‘Scott’, ‘Smith’,
‘Computer Science’, 11);

INSERT INTO students (id, first_name, last_name, major,
current_credits)
VALUES (student_sequence.NEXTVAL, ‘Margaret’, ‘Mason’,
‘History’, 4);

SELECT * FROM students;

Asi obtenemos el siguiente valor:
SELECT student_sequence.NEXTVAL FROM DUAL;

Tambien podemos obtener el valor actual:
SELECT student_sequence.CURRVAL FROM DUAL;

logo shipment4you 342 68 PNG ESP WEB

 

Categorías: Oracle