Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


dbpro - DATABASE, Notas de estudo de Informática

COMANDOS SQL

Tipologia: Notas de estudo

2012

Compartilhado em 15/11/2012

fabio-roberto-fernandes-5
fabio-roberto-fernandes-5 🇧🇷

1 documento

1 / 38

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
PROGRAMAÇÃO
PARA
BANCO DE DADOS
PL/SQL
Prof. Marcos Alexandruk
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26

Pré-visualização parcial do texto

Baixe dbpro - DATABASE e outras Notas de estudo em PDF para Informática, somente na Docsity!

PROGRAMAÇÃO

PARA

BANCO DE DADOS

PL/SQL

Prof. Marcos Alexandruk

SUMÁRIO

1. Conceitos de programação para banco de dados: Introdução ao PL/SQL

2. Declarações

3. Tipos de dados

4. Constantes e variáveis

5. Comandos SQL dentro de um bloco PL/SQL

6. Instruções IF-THEN-ELSE e CASE

7. Instruções LOOP, FOR e WHILE

8. Tratamento de exceções

9. Cursores explícitos e implícitos

10. Procedures

11. Functions

12. Triggers

13. Packages

2. DECLARAÇÕES

Na área DECLARE podemos declarar:

  • constantes
  • variáveis
  • cursores
  • estruturas
  • tabelas

3. TIPOS DE DADOS

3.1. Os tipos de dados simples que podem ser utilizados em declarações PL/SQL são:

TIPOS DESCRIÇÃO

CHAR Alfanumérico, tamanho fixo, limite: 2000 caracteres CHARACTER Idêntico ao CHAR, mantém compatibilidade com outras versões SQL VARCHAR2 Alfanumérico, tamanho variável, limite: 4000 caracteres

VARCHAR E STRING Idêntico ao VARCHAR2, mantém compatibilidade com outras versões SQL CLOB (Character Long Object) Alfanumérico, tamanho variável, limite 4 Gb

LONG Alfanumérico, limites: 2 GB, apenas um por tabela ROWID Armazena os valores dos ROWIDs das linhas das tabelas

BLOB (Binary Long Object)

Binário, tamanho variável, limite: 4 Gb

BFILE (Binary File)

Armazena uma referência a um arquivo externo (que deverá localizar-se na mesma máquina do banco de dados, não permite referência remota) RAW Hexadecimais, tamanho variável, limite: 2 Kb

LONG ROW Hexadecimais, tamanho variável, limite: 2 Gb

NUMBER

Numérico, limite: 38 dígitos Exemplo: NUMBER (10,2) armazena 10 números (8 inteiros e 2 decimais)

SUBTIPOS:

  • DECIMAL
  • DEC
  • DOUBLEPRECISION
  • INTEGER
  • INT
  • NUMERIC
  • REAL
  • SMALLINT
  • FLOAT
  • PLS_INTEGER BINARY_INTEGER Numérico, positivos e negativos, limites: -2147483647 e 2147483647

SUBTIPOS:

  • NATURAL (limites: 0 e 2147483647)
  • NATURALN (limites: 0 e 2147483647, não aceita valores nulos)
  • POSITIVE (limites: 1 e 2147483647)
  • POSITIVEN (limites: 0 e 2147483647, não aceita valores nulos)

DATE Data e hora (formato padrão: DD-MMM-YY TIMESTAMP Data e hora (com milésimos de segundo) BOOLEAN Armazena os valores: TRUE, FALSE ou NULL

3.2. Tipos compostos:

  • RECORD
  • TABLE

3.3. Tipos referenciados:

  • REF CURSOR

4. CONSTANTES E VARIÁVEIS

4.1. CONSTANTES

Para declarações de constantes, a palavra CONSTANT deve aparecer antes do tipo de

dado e a seguir utiliza-se o operador := para atribuir-lhe um valor.

Exemplo:

DECLARE

pi CONSTANT NUMBER(9,7) := 3.1415927; ... BEGIN ... END; /

4.2. VARIÁVEIS

As variáveis são inicializadas de maneira similar às constantes: declarando-se o tipo e

atribuindo-lhe um valor. Variáveis não inicializadas explicitamente recebem o valor

NULL. Não é necessário inicializar uma variável com valor NULL. Pode-se aplicar a

restrição NOT NULL a uma variável. Neste caso ela deverá ser inicializada.

Exemplos:

v1 NUMBER(4):= 1; v2 NUMBER(4):= DEFAULT 1; v3 NUMBER(4) NOT NULL:= 1;

Podemos atribuir valores às variáveis de duas maneiras:

  • Utilizando o operador de atribuição:

total := quant * valor;

  • Utilizando um comando SELECT com a cláusula INTO:

SELECT ra_aluno, nome_aluno INTO ra, aluno FROM aluno;

4.2.1. HERANÇA DE TIPO E TAMANHO

As constantes e variáveis podem herdar o tipo de outras variáveis, de colunas ou até

da linha inteira de uma tabela. Desta forma, diminuem-se as manutenções oriundas

nas alterações realizadas nas colunas de tabelas (ex: tamanho da coluna).

  • Herdando o tipo de uma variável previamente declarada:

nome_da_variavel_2 nome_da_variavel_1%Type;

  • Herdando o tipo de uma coluna de uma tabela:

nome_da_variavel nome_da_tabela.nome_da_coluna%Type;

  • Herdando o tipo de uma linha inteira de uma tabela:

nome_da_variavel nome_da_tabela%Rowtype;

4.2.2. ESCOPO DE VARIÁVEIS

Variáveis definidas dentro de um bloco serão locais para esse bloco e globais para os

sub-blocos. Não serão reconhecidas em outros blocos isolados.

5. Alterar o nome do aluno cujo RA=5 para 'ERNESTO'.

BEGIN

UPDATE ALUNO

SET NOME='ERNESTO'

WHERE RA=5;

END;

6. Excluir da tabela o aluno cujo RA=5.

BEGIN

DELETE FROM ALUNO

WHERE RA=5;

END;

6. INSTRUÇÕES IF-THEN-ELSE E CASE

6.1. IF-THEN-ELSE

Executa um conjunto de ações de acordo com uma ou mais condições.

IF condição_ THEN relação_de_comandos_ [ELSIF condição_ THEN relação_de_comandos_2] [ELSE relação_de_comandos_3] END IF;

Exemplo 1:

DECLARE

V_1 NUMBER(2) := 4;

V_2 VARCHAR2(5);

BEGIN

IF MOD(V_1,2) = 0

THEN V_2 := 'PAR';

ELSE V_2 := 'IMPAR';

END IF;

DBMS_OUTPUT.PUT_LINE ('O número é: ' || V_2); END; /

NOTA: MOD(V1,2) divide o valor de V_1 por 2 e retorna o resto da divisão.

Exemplo 2:

CREATE TABLE ALUNO (

RA NUMBER(9),

NOTA NUMBER(3,1));

INSERT INTO ALUNO VALUES (1,4);

DECLARE

V_RA ALUNO.RA%TYPE := 1;

V_NOTA ALUNO.NOTA%TYPE;

V_CONCEITO VARCHAR2(12);

BEGIN

SELECT NOTA

INTO V_NOTA

FROM ALUNO

WHERE RA = V_RA;

IF V_NOTA <= 5

THEN V_CONCEITO := 'REGULAR';

ELSIF V_NOTA < 7

THEN V_CONCEITO := 'BOM';

ELSE V_CONCEITO := 'EXCELENTE';

END IF;

DBMS_OUTPUT.PUT_LINE ('Conceito: ' || V_CONCEITO); END; /

6.2. CASE

Retorna determinado resultado de acordo com o valor da variável de comparação.

[variável :=] CASE WHEN expressão_1 THEN declaração_ WHEN expressão_2 THEN declaração_ ... ELSE declaração_n END;

EXERCÍCIOS 01:

1. Criar uma tabela conforme segue:

CREATE TABLE ALUNO (

RA NUMBER(9),

DISCIPLINA VARCHAR2(30),

MEDIA NUMBER(3,1),

CARGA_HORA NUMBER(2),

FALTAS NUMBER(2),

RESULTADO VARCHAR2(10));

Inserir uma linha deixando a coluna RESULTADO em branco.

INSERT INTO ALUNO VALUES (1,'DISC 1',7.5,80,20,'');

Criar um bloco PL/SQL para preencher a coluna resultado conforme o seguinte:

Se o aluno obteve média igual ou maior que 7.0 e suas faltas não ultrapassarem 25%

da carga horária da disciplina o resultado será: APROVADO.

Se o aluno obteve média inferior a 7.0 e suas faltas não ultrapassarem 25% da carga

horária da disciplina o resultado será: EXAME.

Para demais casos o resultado será: REPROVADO.

2. Criar uma tabela, conforme segue:

CREATE TABLE PRODUTO (

CODIGO NUMBER(2),

DESCRICAO VARCHAR2(20));

Inserir sete produtos diferentes na tabela acima.

Criar um bloco PL/SQL para apresentar um produto diferente para cada dia da

semana.

Nota: A mensagem acima deverá ser exibida dinamicamente, conforme a data do

sistema (SYSDATE).

Apresentar a seguinte mensagem:

Hoje é TERÇA-FEIRA e o produto em oferta é PRODUTO 3.

7. INSTRUÇÕES LOOP, FOR E WHILE

FOR

Repete um bloco de comando n vezes, ou seja, até que a variável contadora atinja o

seu valor final.

A variável contadora não deve ser declarada na seção DECLARE e deixará de existir

após a execução do comando END LOOP.

FOR v_contador IN valor_inicial..valor_final LOOP bloco_de_comandos END LOOP;

Exemplo 1:

DECLARE

V_AUX NUMBER(2) := 0;

BEGIN

FOR V_CONTADOR IN 1..

LOOP

V_AUX := V_AUX +1;

DBMS_OUTPUT.PUT_LINE (V_AUX);

END LOOP;

END;

Exemplo 2:

DECLARE

V_RA_INICIAL ALUNO.RA%TYPE := 1;

V_RA_FINAL V_RA_INICIAL%TYPE;

V_AUX V_RA_INICIAL%TYPE := 0;

BEGIN

SELECT COUNT(RA)

INTO V_RA_FINAL

FROM ALUNO;

FOR V_CONTADOR IN V_RA_INICIAL..V_RA_FINAL

LOOP

V_AUX := V_AUX +1;

DBMS_OUTPUT.PUT_LINE ('Total de alunos: ' || V_AUX); END LOOP; END; /

WHILE

Repete um bloco de comandos enquanto a condição que segue o comando WHILE for

verdadeira.

Exemplo 1:

DECLARE

V_AUX NUMBER(2) := 0;

BEGIN

WHILE V_AUX < 10

LOOP

V_AUX := V_AUX +1;

DBMS_OUTPUT.PUT_LINE (V_AUX);

END LOOP;

END;

Exemplo:

DECLARE

V_AUX NUMBER(2) := 0;

BEGIN

LOOP

V_AUX := V_AUX +1;

DBMS_OUTPUT.PUT_LINE (V_AUX);

IF V_AUX = 10

THEN EXIT;

END IF;

END LOOP;

END;

EXERCÍCIO

Crie uma tabela chamada CIRCULO com as seguintes colunas:

RAIO NUMBER(2),

AREA NUMBER(8,2)

CREATE TABLE CIRCULO (

RAIO NUMBER(2),

AREA NUMBER(8,2));

Desenvolva um programa em PL/SQL para inserir os raios com valores 1 a 10 e as

respectivas áreas na tabela acima.

SOLUÇÃO 1: WHILE

DECLARE

PI CONSTANT NUMBER(9,7) := 3.1415927;

RAIO NUMBER(2);

AREA NUMBER(8,2);

BEGIN

RAIO := 1;

WHILE RAIO <=

LOOP

AREA := PI*POWER(RAIO,2);

INSERT INTO CIRCULO VALUES (RAIO,AREA);

RAIO := RAIO+1;

END LOOP;

END;

SOLUÇÃO 2: FOR

DECLARE

PI CONSTANT NUMBER(9,7) := 3.1415927;

RAIO NUMBER(2) := 1;

AREA NUMBER(8,2);

BEGIN

FOR CONTADOR IN 1..

LOOP

AREA := PI*POWER(RAIO,2);

INSERT INTO CIRCULO VALUES (RAIO,AREA);

RAIO := RAIO +1;

END LOOP;

END;

LABELS

Utilizados para nomear blocos ou sub-blocos.

Devem localizar-se antes do início do bloco e preceder pelo menos um comando.

Se não houver necessidade de nenhum comando após o label, deve-se utilizar o

comando NULL.

<<NOME_DO_LABEL>>

DECLARE

BEGIN

RELAÇÃO_DE_COMANDOS

<<NOME_DO_LABEL>>

RELAÇÃO DE COMANDOS

END;

Um label também pode ser aplicado a um comando de repetição LOOP.

<>

LOOP

LOOP

-- SAIR DOS DOIS LOOPS

EXIT PRINCIPAL WHEN ...

END LOOP;

END LOOP PRINCIPAL;

GOTO

Utilizado para desviar um fluxo de um bloco PL/SQL para determinado label.

Não pode ser utilizado para:

  • Desviar o fluxo para dentro de um IF;
  • Desviar o fluxo de um IF para outro;
  • Desviar o fluxo para dentro de um sub-bloco;
  • Desviar o fluxo para um bloco externo ao bloco corrente;
  • Desviar o fluxo de uma EXCEPTION para o bloco corrente e vice-versa.

GOTO nome_do_label

Exemplo 1:

<>

DECLARE

V_NOME ALUNO.NOME%TYPE;

BEGIN

SELECT COUNT(RA)

INTO V_CONTA

FROM ALUNO;

IF V_CONTA = 10

GOTO FIM;

ELSE INSERT INTO ALUNO VALUES (20,'SILVA');

END IF;

<>

DBMS_OUTPUT.PUT_LINE('Fim do programa'); END; /

8. TRATAMENTO DE EXCEÇÕES

Exceções são erros ou imprevistos que podem ocorrer durante a execução de um

bloco PL/SQL.

Nesses casos, o gerenciador de banco de dados aborta a execução e procura uma

área de exceções.

As exceções podem ser:

  • Predefinidas
  • Definidas pelo usuário

PREDEFINIDAS

Disparadas automaticamente quando, no bloco PL/SQL, uma regra Oracle for violada.

Podem ser identificadas por um nome e um número.

EXCEPTION

WHEN nome_da_exceção THEN relação_de_comandos; WHEN nome_da_exceção THEN relação_de_comandos;

ERRO NOME DESCRIÇÃO

ORA-00001 DUP_VAL_ON_INDEX

Tentativa de armazenar valor duplicado em uma coluna que possui chave primária ou única.

ORA-01012 NOT_LOGGED_ON Tentativa acessar o banco de dados sem estar conectado a ele.

ORA-01403 NO_DATA_FOUND

Ocorre quando um comando SELECT ... INTO não retorna nenhuma linha.

ORA-01422 TOO_MANY_ROWS

Ocorre quando um comando SELECT ... INTO retorna mais de uma linha.

ORA-01476 ZERO_DIVIDE Tentativa de dividir qualquer número por zero.

Exemplo:

DECLARE

V_RA ALUNO.RA%TYPE;

V_NOME ALUNO.NOME%TYPE;

BEGIN

SELECT RA, NOME

INTO V_RA, V_NOME

FROM ALUNO

WHERE RA=30;

DBMS_OUTPUT.PUT_LINE(V_RA ||' - '|| V_NOME);

EXCEPTION

WHEN NO_DATA_FOUND THEN

DBMS_OUTPUT.PUT_LINE ('Não há nenhum aluno com este RA'); WHEN TOO_MANY_ROWS THEN DBMS_OUTPUT.PUT_LINE ('Há mais de um aluno com este(s) RA(s)'); WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('Erro desconhecido'); END;

EXERCÍCIO

Elabore um programa em PL/SQL que faça o seguinte tratamento de exceção:

  • Informe tentativa de inserir valor duplicado numa coluna que é chave primária.

DECLARE

BEGIN

INSERT INTO ALUNO VALUES (1,'ANTONIO');

EXCEPTION

WHEN DUP_VAL_ON_INDEX THEN

DBMS_OUTPUT.PUT_LINE ('Já existe um aluno com este RA'); END; /

DEFINIDAS PELO USUÁRIO

Além dos erros tratados automaticamente pelo Oracle, regras de negócio específicas

podem ser tratadas.

As exceções definidas pelo usuário devem ser declaradas e chamadas explicitamente

pelo comando RAISE.

DECLARE

nome_da_exceção EXCEPTION; BEGIN ... IF ... THEN RAISE nome_da_exceção; END IF; ... EXCEPTION WHEN nome_da_exceção THEN relação_de_comandos END; /

Exemplo 1:

DECLARE

V_RA ALUNO.RA%TYPE;

V_NOTA ALUNO.NOTA%TYPE;

V_CONTA NUMBER(2);

CONTA_ALUNO EXCEPTION;

BEGIN

SELECT COUNT(RA)

INTO V_CONTA

FROM ALUNO;

IF V_CONTA = 10 THEN

RAISE CONTA_ALUNO;

ELSE INSERT INTO ALUNO VALUES (20,'SILVA');

END IF;

EXCEPTION

WHEN CONTA_ALUNO THEN

DBMS_OUTPUT.PUT_LINE('Não foi possível incluir: turma cheia'); END; /

Exemplo 2:

DECLARE

V_RA ALUNO.RA%TYPE := &RA;

V_NOME ALUNO.NOMEA%TYPE := '&NOME';

BEGIN

INSERT INTO ALUNO VALUES (V_RA,V_NOME);

EXCEPTION

WHEN DUP_VAL_ON_INDEX THEN

DBMS_OUTPUT.PUT_LINE('Este RA já foi utilizado'); END; /

Exemplo:

DECLARE

CURSOR c_cliente IS SELECT codigo, nome FROM cliente; v_cliente c_cliente%rowtype; BEGIN OPEN c_cliente; LOOP FETCH c_cliente INTO v_cliente; EXIT when c_cliente%notfound; DBMS_OUTPUT.PUT_LINE('Cliente: '||v_cliente.nome); END LOOP; CLOSE c_cliente; END;

9.1.2. UTILIZANDO: FOR

O comando FOR ... LOOP, quando aplicado a um cursor, executa automaticamente as

seguintes ações:

  • Cria a variável do tipo registro que receberá os dados;
  • Abre (OPEN) o cursor;
  • Copia as linhas uma a uma (FETCH), a cada interação do comando;
  • Controla o final do cursor;
  • Fecha (CLOSE) o cursor.

NOTA: Caso seja necessário sair do loop do comando FOR durante sua execução, o

cursor deverá ser fechado explicitamente com o comando CLOSE.

Exemplo:

DECLARE

CURSOR c_cliente IS SELECT codigo, nome FROM cliente; BEGIN FOR v_cliente IN c_cliente LOOP DBMS_OUTPUT.PUT_LINE('Cliente: '|| v_cliente.nome); END LOOP; END;

NOTA:

As variáveis devem ser visíveis no ponto da declaração do cursor:

DECLARE

V_RA ALUNO.RA%TYPE;

C_ALUNO IS

SELECT * FROM ALUNO

WHERE RA = V_RA;

CORRETO

DECLARE

C_ALUNO IS

SELECT * FROM ALUNO

WHERE RA = V_RA;

V_RA ALUNO.RA%TYPE;

ERRADO: V_RA não foi declarado antes de ser referenciado.

EXERCÍCIOS:

1. Criar a tabela PRODUTO:

CREATE TABLE PRODUTO (

CODIGO NUMBER(4),

VALOR NUMBER(7,2));

Inserir os valores:

INSERT INTO PRODUTO VALUES (1000,300);

INSERT INTO PRODUTO VALUES (1001,500);

INSERT INTO PRODUTO VALUES (2000,300);

INSERT INTO PRODUTO VALUES (2001,500);

Criar um bloco PL/SQL para atualizar os preços conforme segue:

  • Produtos com CODIGO inferior a 2000: Acrescentar 10% ao VALOR atual.
  • Produtos com CODIGO igual ou superior a 2000: Acrescentar 20% ao VALOR atual.

2. Criar a tabela ALUNO:

Observação: Similar ao exercício 1 da página 10. Porém, utiliza cursor.

CREATE TABLE ALUNO (

RA NUMBER(9),

DISCIPLINA VARCHAR2(30),

MEDIA NUMBER(3,1),

CARGA_HORA NUMBER(2),

FALTAS NUMBER(2),

RESULTADO VARCHAR2(10));

Inserir uma linha deixando a coluna RESULTADO em branco.

INSERT INTO ALUNO VALUES (1,'DISC 1',7.5,80,20,'');

INSERT INTO ALUNO VALUES (2,'DISC 1',5.5,80,20,'');

INSERT INTO ALUNO VALUES (3,'DISC 1',7.5,80,40,'');

Criar um bloco PL/SQL para preencher a coluna resultado conforme o seguinte:

  • Se o aluno obteve média igual ou maior que 7.0 e suas faltas não ultrapassarem

25% da carga horária da disciplina o resultado será: APROVADO.

  • Se o aluno obteve média inferior a 7.0 e suas faltas não ultrapassarem 25% da

carga horária da disciplina o resultado será: EXAME.

  • Para demais casos o resultado será: REPROVADO.