7 Linguagem - PL SQL
7 Linguagem - PL SQL
7 Linguagem - PL SQL
BANCO
DE
DADOS II
7. LINGUAGEM PL/SQL
7.1. INTRODUÇÃO
7.2.1. Integração
SQL
OUTROS
APLICAÇÃO SQL
DBMS
SQL
SQL
IF ... THEN ORACLE
SQL
APLICAÇÃO ELSE com
SQL
END IF;
SQL PL/SQL
7.2.3. Características
Operações Permitidas
Tratar erros;
Criar labels para controlar o fluxo de execução;
Utilizar comando de repetição e comparação.
Criar triggers (gatilhos) para garantia de integridade (restrições), segurança,
etc.
Ilustrando:
DECLARE – opcional
Declarações – variáveis, cursores, constantes, estruturas, tabelas, exceções definidas
pelo usuário
BEGIN - obrigatório
Estruturas executáveis (comandos)
Instruções SQL (manipular dados do banco de dados)
Instruções PL/SQL (manipular dados no bloco)
EXCEPTION - opcional
Tratamento de exceções (pode conter outros blocos)
Ações a serem desempenhadas qdo ocorrem erros ou condições anormais
END; - obrigatório
Exemplo de instruções:
Declare
v_nascimento DATE;
v_codigo NUMBER(5) NOT NULL := 10;
v_cidade VARCHAR2(35) := ‘Assis’;
v_numero CONSTANT NUMBER := 1234;
Identificador := expr;
Exemplo de instruções:
v_nascimento := ’30-AGO-01’
Exemplo de instruções:
v_descricao VARCHAR2(30);
v_contador BINARY_INTEGER := 0;
v_soma NUMBER(10,2) := 0;
v_reserva DATE := SYSDATE + 7;
c_taxa CONSTANT NUMBER(5,2) := 15.30;
v_filhos BOOLEAN NOT NULL := TRUE;
v_preco1 NUMBER(10,2) := 1500
v_preco2 NUMBER(10,2) := 2500
v_aumento BOOLEAN := (v_preco1 < v_preco2);
Utilizado para declarar uma variável de acordo com uma definição de coluna de
banco de dados ou de acordo com outra variável anteriormente declarada.
Exemplo de instruções:
…..
v_descricao depto.descricao%TYPE
v_salario v_soma%TYPE := 0;
…..
7.4.10. DBMS_OUTPUT.PUT_LINE
Exemplo de instruções:
SET SERVEROUTPUT ON
ACCEPT v_anual PROMPT ‘Entre com o salário anual.:’
DECLARE
v_salario NUMBER(10,2) := &v_anual;
BEGIN
v_salario := v_salario/12;
DBMS_OUTPUT.PUT_LINE (‘O salário mensal é ‘ | | TO_CHAR(v_salario));
END;
Delimitadores
Identificadores
Literais
Crie prefixos de dois hífens (--) para comentários de uma única linha;
Coloque os comentários de várias linhas entre os símbolos /* e */.
…..
v_salario NUMBER(10,2);
BEGIN
/* computer o salário annual baseado nos salários mensais
para usá-lo em cálculos */
v_salário := &v_anual * 12;
END; -- Final do bloco
Exemplo de instruções:
CH(10) = ENTER
Exemplo de instruções:
v_nome := LOWER(v_nome);
TO_CHAR
valor (valor, fmt) string de caractere, número ou data
: é uma
TO_DATE (valor, fmt)
TO_NUMBER (valor, fmt)
fmt : é o modelo de formato usado para converter o valor
Exemplo de instruções:
v_data := TO_DATE (‘September 20, 2001’, ‘Month DD, YYYY’);
Operador Operação
**, NOT Exponenciação, negação, lógica
+, - Identidade, negação
*, / Multiplicação, divisão
+, -, || Adição, subtração, concatenação
=, !=, <, >, <=, >=, IS NULL, LIKE, BETWEEN, IN Comparação
AND Conjunção
OR Disjunção
Exemplo de instruções:
DECLARE
v_codigo NUMBER(2);
v_descricao VARCHAR2(15);
BEGIN
SELECT codigo, descricao
INTO v_codigo, v_descricao
FROM depto
WHERE codigo=1;
END;
*/ devem retornar apenas um valor, caso contrário ocorrerá erros */
DECLARE
v_codigo depto.codigo%TYPE;
v_descricao depto.descricao%TYPE;
BEGIN
SELECT codigo, descricao
INTO v_codigo, v_descricao
FROM depto
WHERE codigo=2;
END;
*/ devem retornar apenas um valor, caso contrário ocorrerá erros */
Prof. Dr. Alex S. R. S. Poletto – Email: apoletto@femanet.com.br
Coordenadoria de Informática 11
Disciplina
BANCO
DE
DADOS II
DECLARE
v_soma_salario professor.salario%TYPE;
v_codigo NUMBER NOT NULL := 2;
BEGIN
SELECT SUM (salario)
INTO v_soma_salario
FROM professor
WHERE codigo=v_codigo;
END;
*/ devem retornar apenas um valor, caso contrário ocorrerá erros */
Exemplo de instruções:
BEGIN
INSERT INTO professor(codigo, nome, salario, nascimento)
VALUES (codigo_sequence.NEXTVAL, ‘Douglas’, 1450, ’10-DEC-00’);
END;
Exemplo de instruções:
DECLARE
v_aumento professor.salario%TYPE := 245;
BEGIN
UPDATE professor
SET salario = salario + v_aumento
WHERE codigo=10;
END;
Exemplo de instruções:
DECLARE
v_codigo professor.codigo%TYPE := 9;
BEGIN
DELETE FROM professor
WHERE codigo=v_codigo;
END;
Exemplo de instruções:
VARIABLE rows_deleted VARCHAR2(30)
DECLARE
v_codigo NUMBER := 4;
BEGIN
DELETE FROM professor
WHERE codigo=v_codigo;
: rows_deleted := (SQL%ROWCOUNT | | ‘ rows deleted.’);
END;
/
PRINT rows_deleted
Você pode alterar o fluxo lógico de instruções dentro do bloco PL/SQL com
diversas estruturas para controle. Esta lição aborda os dois tipos de estruturas
para controle do PL/SQL: construções condicionais com a instrução IF e
estruturas para controle LOOP.
Instruções IF
IF condição THEN
instruções
[ELSIF condição THEN
instruções;]
[ELSE
Instruções;]
END IF
Instrução IF-THEN-END IF
Exemplo de instruções:
.....
IF nome = ‘Alex’ THEN
v_novo_salario := salario * 1.20;
END IF;
......
Instrução IF-THEN-ELSE-END IF
Exemplo de instruções:
.....
IF media >= 7 THEN
v_mensagem := ‘Aprovado’;
ELSE
v_mensagem := ‘Reprovado’;
END IF;
.....
Instrução IF-THEN-ELSIF-THEN-END IF
Definir aumento salarial de acordo com as faixas salariais: até 500.00 – 25%,
de 500.01 até 1500.00 -15% e acima de 1500.01 – 10%.
Exemplo de instruções:
.....
IF salario < 500.00 THEN
v_novo_salario := salario * 1.25;
ELSIF salario < 1000.00 THEN
v_novo_salario := salario + (salario*15/100);
ELSE
v_novo_salario := salario * 1.10;
END IF;
.....
O PL/SQL oferece diversos recursos para estruturar loops para repetirem uma
instrução ou seqüência de instruções várias vezes.
LOOP Básico
LOOP
Instrução1;
.....
EXIT [WHEN condição];
Instruções;]
END LOOP;
Exemplo de instruções:
DECLARE
v_codigo produto.codigo%TYPE := 21;
v_contador NUMBER(2) := 1;
BEGIN
LOOP
INSERT INTO produto (codigo,numero)
VALUES(v_codigo, v_contador);
v_contador := v_contador + 1;
EXIT WHEN v_contador > 10;
END LOOP;
END;
FOR LOOP
Exemplo de instruções
DECLARE
v_codigo pedido.codigo%TYPE := 10;
BEGIN
FOR i IN 1..5 LOOP
INSERT INTO pedido (pedido, produto)
VALUES (v_codigo, i);
END LOOP;
END;
WHILE LOOP
.
END LOOP;
Usar um WHILE LOOP para repetir instruções enquanto um condição for
TRUE;
Utiliza-se o WHILE LOOP para repetir uma seqüência de instruções até a
condição para controle não ser mais TRUE. A condição é avaliada ao início de
cada iteração. O LOOP terminará quando a condição for FALSE. Se a condição
for FALSE no início do loop, nenhuma iteração futura será executada.
condição : é uma expressão ou variável booleana;
instrução : pode ser uma ou mais instruções SQL ou PL/SQL.
Exemplo de instruções:
O Oracle Server usa áreas de trabalho chamadas áreas SQL particulares para
executar instruções SQL e para armazenar informações de processamento.
Você pode usar cursores do PL/SQL para nomear uma área SQL particular e
acessar suas informações armazenadas. O cursor orienta todas as fases do
processamento.
São usados para consultas que retornam mais de uma linha. Os cursores
explícitos são declarados e nomeados pelo programador e manipulados por
meio de instruções específicas nas ações executáveis do bloco.
Pode processar além da primeira linha retornada pela consulta, linha por
linha;
Controla que linha está sendo processada no momento;
Permite que o programador controle as linhas manualmente no bloco
PL/SQL.
Declarando o CURSOR
CURSOR cursor_name IS
select_statement;
Exemplos de instruções:
DECLARE
v_matricula professor.matricula%TYPE;
v_nome professor.nome%TYPE;
CURSOR professor_cursor IS
SELECT matricula, nome
FROM professor
CURSOR depto_cursor IS
SELECT * FROM depto
WHERE codigo=10;
BEGIN
.....
Abrir o cursor
OPEN cursor_name;
Exemplos de instruções:
.....
OPEN defined_cursor;
LOOP
FETCH defined_cursor INTO defined_variables
EXIT WHEN ...;
.....
-- Processo dos dados
.....
END;
DECLARE
v_codigo professor.codigo%TYPE;
v_nome professor.nome%TYPE;
CURSOR professor_cursor IS
SELECT codigo, nome
FROM professor
BEGIN
OPEN professor_cursor;
FOR i IN 1..5 LOOP
FETCH professor_cursor INTO v_codigo, v_nome;
.....
END LOOP;
CLOSE professor_cursor;
END;
Fechar o CURSOR
CLOSE cursor_name;
%ISOPEN
%NOTFOUND
DECLARE
v_codigo professor.codigo%TYPE;
v_nome professor.nome%TYPE;
CURSOR professor_cursor IS
SELECT codigo, nome
FROM professor
BEGIN
OPEN professor_cursor;
LOOP
FETCH professor_cursor INTO v_codigo, v_nome;
EXIT WHEN professor_cursor%ROWCOUNT > 5
OR professor_cursor%NOTFOUND;
.....
END LOOP;
CLOSE professor_cursor;
END;
Tipos de exceção
Exceções predefinidas
Nome da Exceção Número Descrição
ACCESS_INTO_NULL ORA-06530 Tentativa de atribuir valores aos
atributos de um objeto não
inicializado
COLLECTION_IS_NULL ORA-06531 Tentativa de aplicação de métodos
de conjunto diferentes de EXISTS
para um varray ou tabela aninhada
não inicializada
BEGIN
EXCEPTION
WHEN NO_DATA_FOUND THEN
statement1;
statement2;
WHEN TOO_MANY_ROWS THEN
statement1;
WHEN DUP_VAL_ON_INDEX THEN
statement1;
statement2;
statement3;
END;
DECLARE
v_error_code NUMBER;
v_error_message VARCHAR(255);
BEGIN
....
EXCEPTION
....
WHEN OTHERS THEN
ROLLBACK;
v_error_code := SQLCODE;
v_error_message := SQLERRM;
INSERT INTO errors VALUES(v_error_code, v_error_message);
END;
Movimento Relacional
TABREG
TABFUN
MATRICULA
TABCAR MATRICULA
CARGO
CODIGO NOME
DATA
DESCRICAO SALARIO
SALARIO
ADMISSAO
CARGO
TABDEP
MATRICULA
SEQUENCIA
NOME
NASCIMENTO
Tabela de Cargos
CREATE TABLE tabcar
(codigo NUMBER(2),
descricao VARCHAR2(35) NOT NULL,
CONSTRAINT tabcar_codigo_pk PRIMARY KEY (codigo));
Tabela de Funcionários
CREATE TABLE tabfun
(matricula NUMBER(5),
nome VARCHAR2(35) NOT NULL,
salario NUMBER(9,2) CHECK (salario > 0),
admissao DATE NOT NULL,
cargo NUMBER(2),
CONSTRAINT tabfun_matricula_pk PRIMARY KEY (matricula),
CONSTRAINT tabfun_cargo_fk FOREIGN KEY (cargo)
REFERENCES tabcar(codigo));
Tabela de Dependentes
CREATE TABLE tabdep
(matricula NUMBER(5),
sequencia NUMBER(2),
nome VARCHAR2(35) NOT NULL,
nascimento DATE NOT NULL,
CONSTRAINT tabdep_matricula_pk PRIMARY KEY (matricula,sequencia),
CONSTRAINT tabdep_matricula_fk FOREIGN KEY (matricula)
REFERENCES tabfun(matricula));
Tabela de Registros
CREATE TABLE tabreg
(matricula NUMBER(5),
cargo NUMBER(2),
data DATE,
salario NUMBER(9,2),
CONSTRAINT tabreg_pk PRIMARY KEY (matricula, cargo, data));
7.11.2.1. Objetivos
Ambiente de
Chamada
Caso você queira usar uma codificação automática para a matricula (auto-
numeração), crie uma seqüência e troque a variável v_matricula por essa
seqüência.
.......
VALUES (num_fun.NEXTVAL, v_nome, v_salario, v_admissão, v_cargo);
......
SET SERVEROUTPUT ON
7.11.2.7. Sumário
Exercícios:
1. Faça um procedimento para excluir funcionários.
7.11.3.1. Objetivos
PL/SQL Block: é o corpo da função que define as ações que serão executadas
quando a função for executada.
OBS: o bloco PL/SQL deve ter pelo menos uma instrução RETURN.
RETURN: retorna um valor da função para o ambiente de chamada.
Ambiente de
Chamada
Executando a função
EXECUTE :g_salario := consulta_salario (11); ou
ACCEPT num_matricula PROMPT ‘Digite o número da matricula:’
EXECUTE :g_salario := consulta_salario (&num_matricula);
Consultando o valor
PRINT g_salario
SET SERVEROUTPUT ON
DECLARE
v_salario tabfun.salario%TYPE;
BEGIN
v_salario := consulta_salario (12);
DBMS_OUTPUT.PUT_LINE (v_salario);
END;
/
DECLARE
v_quant NUMBER(5);
BEGIN
v_quant := mudanca_salario (12);
DBMS_OUTPUT.PUT_LINE (v_quant);
END;
/
Sintaxe:
Exemplo1:
7.11.3.9. Observações
Uma função definida pelo usuário obtém apenas parâmetros IN, e não OUT
ou IN OUT;
Os tipos de dados devem ser tipos de dados SQL válidos, CHAR, DATE ou
NUMBER;
Os tipos de dados não podem ser tipos PL/SQL como BOOLEAN, RECORD
ou TABLE;
Comandos INSERT, UPDATE ou DELETE não são permitidos.
7.11.3.10. Sumário
Exercícios:
Procedimentos Funções
Executar como uma instrução PL/SQL Chamar como parte de uma expressão
Tipo de dados sem RETURN Deve conter um tipo de dados RETURN
Pode retornar nenhum, um ou muitos valores Deve retornar um valor único
Desempenho melhorado;
o Reduzir o número de chamadas ao banco de dados e diminuir o
tráfico na rede;
o Compartilhar execuções SQL por vários usuários.
Manutenção melhorada;
o Modificar rotinas on-line sem interferir com outros usuários;
o Modificar uma rotina que afetará várias aplicações.
Segurança de dados e Integridade melhorada.
o Controle sobre acessos indiretos aos objetos de banco de dados
executados por funcionários sem privilégios;
o Assegurar que ações relacionadas sejam executadas
conjuntamente.
DESC user_objects
DESC user_source
DESC user_errors
7.11.5.1. Objetivos
INSERT
UPDATE
DELETE
Os gatilhos são divididos em dois tipos, no qual defini quantas vezes o corpo
do gatilho deverá ser executado quando ocorre um evento de acionamento.
Testando o gatilho:
UPDATE tabfun
SET salario = salario*1.10
WHERE matricula = 10;
Exemplo2: Criando um gatilho de linha para não deixar reajustar o salário dos
funcionários em mais de 20%.
Testando o gatilho:
UPDATE tabfun
SET salario = salario * 1.30
WHERE matricula = 10;
Testando o gatilho:
Testando o gatilho:
Desabilitar um gatilho
ALTER TRIGGER nome_trigger DISABLE
Carregar um gatilho
START caminho nome_gatilho.SQL
Compilar um gatilho
ALTER TRIGGER
4.10.5.11. nome_gatilho
REMOVENDO COMPILE
GATILHOS
Sintaxe:
Exemplo1:
DROP TRIGGER salario_fixo;
Exercícios:
1) Faça um gatilho que não permita inserir um funcionário com data de
admissão maior que a data do servidor (SYSDATE).
2) Faça um gatilho que não permita alterar ou incluir um funcionário com
salário igual a zero.
Todos os itens do corpo que não estão listados na especificação são privados
do pacote. Os itens privados só podem ser usados dentro do corpo do pacote.
Usando uma combinação de itens públicos e privados, é possível construir um
pacote cuja complexidade fica oculta do mundo exterior. Esse é um dos
principais objetivos de toda programação: ocultar a complexidade de seus
usuários.
7.11.6.1. Objetivos
PROCEDURE update_tabfun_salario (
n_matricula IN tabfun.matricula%TYPE,
n_fator IN NUMBER
) AS
v_tabfun_count INTEGER;
BEGIN
--- conta o número de produtos com o valor de n_matricula fornecido
--- será 1 se o funcionário existir
SELECT COUNT(*)
INTO v_tabfun_count
FROM tabfun
WHERE matricula = n_matricula;
SELECT tabfun_pacote.get_tabfun_ref_cursor
FROM dual;
OBJECT_NAME PROCEDURE_NAME
------------------------------ ------------------------------
TABFUN_PACOTE GET_TABFUN_REF_CURSOR
TABFUN_PACOTE UPDATE_TABFUN_SALARIO