Você está na página 1de 8

Bases de Dados 2

Ficha 1- Revises de SQL

Objectivos Conhecer a configurao do laboratrio e rever a utilizao da base de dados Oracle.


Utilizar a plataforma Oracle via o cliente SQL-Worksheet. Implementar procedimentos em PL-SQL no servidor. Utilizar cursores para acesso a tabelas. Implementar um pacote PL-SQL no servidor.

Recursos No decurso da aula dever utilizar um servidor Oracle 10g (local ou servidor da disciplina). Necessitar ainda de consultar:

Scripts para criao de base de dados de exemplo Partes seleccionadas de manuais do Oracle. Manual de referncia do Oracle 10g

1. Inicio: Ligao base de dados ORACLE


Activar o cliente SQL para ligao base de dados Oracle no seu posto de trabalho. Pode usar a base de dados local ou o servidor (que bem mais rpido!). Para a local deve usar o utilizador scott/tiger (default no Oracle), deixando o campo Service vazio (a ligao efectuada base de dados local no seu disco). Para o servidor use o utilizador bd<seuNAluno> sendo a password indicada na aula e o service servidor-bd.

Exerccio 1.1: Utilize as tabelas de sistema (sug. sys.all_tables) do Oracle e a instruo DESC para determinar as tabelas existentes. De seguida carregue a base de dados faculdade j utilizada na disciplina de Bases de Dados 1, para o seu utilizador, no esquecendo a insero de dados. Obtenha os valores previamente inseridos na base de dados para a tabela alunos.

2. Construo de Procedimentos PLSQL.

A criao de procedimentos em PLSQL conseguida pela instruo:

CREATE [OR REPLACE] PROCEDURE <nome do procedimento> IS BEGIN Instrues PLSQL; END;

Exemplo: Um exemplo de procedimento :

CREATE [OR REPLACE] PROCEDURE olamundo IS BEGIN dbms_output.put_line('Ola Mundo'); END; /

Ateno ao smbolo / no fim da declarao!

Exerccio 2.1: Num terminal SQL introduza o cdigo do exemplo acima. De seguida, execute o procedimento olamundo com o comando:
exec olamundo;

Nota: No esquecer de previamente ter feito: set serveroutput on

Exerccio 2.2: Para este exerccio devem ser utilizadas trs tabelas: a tabela alunos, a tabela disciplinas e a tabela inscricoes, e que corresponde a uma verso simplificada da situao "alunos que se inscrevem em disciplinas". Estas tabelas devem ter sido criadas no exerccio 1.1.

Verifique que percebe o que efectuado pelos scripts e em particular certifique-se que percebe: as condies de integridade impostas pelo modelo implementado; o uso que feito das sequncias; A tabela de inscricoes serve para implementar uma relao N:M e como tal a aplicao de acesso BD no quer preocupar-se com ela.

A. Definir o procedimento inscrever_aluno(nome_aluno, nome_disciplina). Vamos assumir aqui que o nome do aluno e o nome da disciplina so vlidos (i.e. j existem na BD).

B. Faa agora as seguinte inscries: + o Joaquim Pires Lopes em Bases de Dados I + o Joaquim Pires Lopes em Bases de Dados II

C. Verifique que as inscries foram efectuadas.

Exerccio 2.3: Fazer um procedimento que regista um novo aluno novo_aluno(nome, sexo,nome_curso). O nmero de aluno atribudo automaticamente por uma sequncia (e que j est definida).

Dica: o valor corrente da sequncia <nome_sequencia>.currval. Faa agora a insero do aluno Z Manel do sexo masculino no curso Engenharia Informtica:
exec novo_aluno('Z Manel','M','Engenharia Informtica');

ou ainda:
exec novo_aluno(nome_curso=>'Engenharia Informtica', nome=>'Z Manel',sexo=>'M');

Faa um procedimento nova_disciplina(nome,departamento) para definir uma nova disciplina.

Certifique-se de que funciona:


exec nova_disciplina('Gesto Industrial','Dep. Mecanica');

3. Cursores em PL/SQL.
Comecemos por um cursor simples que faz o percurso da tabela alunos, e que usado por um procedimento ver_alunos, e que poderia ser:
create or replace procedure teste_cursor Is cursor cur_aluno is select * from alunos; v_aluno alunos%ROWTYPE; begin open cur_aluno; fetch cur_aluno into v_aluno; dbms_output.put_line(v_aluno.num_aluno || v_aluno.nome); close cur_aluno; end;

Podemos fazer um ciclo com:

loop fetch cur_aluno into v_aluno; exit when cur_aluno%NOTFOUND; dbms_output.put_line(v_aluno.num_aluno || ' ' || v_aluno.nome); end loop;

ou ainda com variveis de percurso de cursores:


BEGIN FOR v IN cur_aluno LOOP dbms_output.put_line(v.nome_aluno || ' ' || v.sexo_aluno); END LOOP;

Note-se que nesta modalidade no necessrio controlar todas as operaes sobre o cursor (OPEN, FETCH,CLOSE).

Exerccio 3.1.: Adicionar o procedimento ver_alunos que mostra os alunos e os cursos em que se encontram inscritos, p.e.:
Ana Maria Fonseca est inscrita em Engenharia Electrotecnica Joana Ramalho Silva est inscrita em Matematica Joaquim Pires Lopes est inscrito em Engenharia Informatica Paula Antunes est inscrita em Engenharia do Ambiente

Os cursores admitem parmetros. Assim podemos ter um cursor para visualizar informao sobre alunos e o mesmo cursor para visualiza informao sobre alunas.
cursor cur_aluno(sx aluno.sexo_aluno%type) is select * from aluno where sx = sexo_aluno;

e no momento de abrir o cursor podemos escrever:


open cur_aluno('M'); ou for c in cur_aluno('M') loop

Exerccio 3.2: Adicione um procedimento que actualiza uma tabela contendo os cdigos dos N alunos (N indicado como parmetro) com mais inscries.

Exerccio 3.3: Corrigir o procedimento inscrever_aluno(nome_aluno, sexo_aluno, nome_disciplina) que inscreva todos os alunos iniciados por nome_aluno em todas as cadeiras iniciadas por nome_disciplina. Caso o aluno no exista, o sistema deve escrever um aviso e criar um novo aluno, antes de efectuar a insero. Caso a disciplina no exista, o sistema deve escrever um aviso e criar uma nova disciplina, antes de efectuar a insero. Caso a disciplina j tenha o aluno inscrito, o sistema deve escrever apenas:
ignorado: O aluno nome_aluno j est inscrito em nome_disciplina.

Sugesto: Utilize mecanismos de gesto de excepes, pode consultar no manual.

4. Construo de Pacotes.
As aplicaes ao acederem BD vo usar os procedimentos que so fornecidos pelo programador da BD. Esses procedimentos podem estar agrupados em pacotes (packages). A definio de um pacote (package) em PLSQL feita em duas partes:

A definio da interface (instruo CREATE [OR REPLACE] PACKAGE <nome do


pacote>)

A definio da implementao (ou corpo) do pacote atravs da instruo CREATE


PACKAGE BODY ...

De seguida define-se uma API para acesso BD. A API pode chamar-se univ_api. A interface do package definida da seguinte forma:
create or replace package univ_api is procedure inserir_aluno(nome in aluno.nome_aluno%TYPE, sexo in aluno.sexo_aluno%TYPE, disciplina in disciplina.cod_disciplina%TYPE); procedure nova_disciplina( nome in disciplina.nome_disciplina%TYPE); function disciplina_do_aluno(numero in aluno.num_aluno%TYPE) RETURN disciplina.nome_disciplina%TYPE;

function numero_do_aluno(nome in aluno.nome_aluno%TYPE) RETURN aluno.num_aluno%TYPE; end univ_api; /

Para testar o resultado das funes podem-se usar as variveis de ambiente em SQL Plus da seguinte forma:
SQL> var tmp number SQL> exec :tmp:= univ_api.numero_do_aluno('Joaquim Pires Lopes')

e ento:
SQL> print :tmp TMP --------1

O ORACLE tem um conjunto de pacotes pr-definidos para diferentes funcionalidades. Destacam-se: + dbms_output com os mtodos: put_line(arg), put(arg) entre outros. + dbms_refresh como os mtodos make, delete, refresh para gerir grupos de refrescamento. Para visualizar o resultado da instruo dbms_output.put_line('OLA MUNDO') faa: 1. Colocar disponivel o resultado do output (colocar uma flag a on): set serveroutput on 2. Executar exec dbms_output.put_line('OLA Mundo'); ou
begin dbms_output.put_line('OLA Mundo'); end; /

Note-se que embora o resultado seja idntico, neste segundo caso o que foi feito foi: + primeiro declarou-se um bloco PLSQL annimo (desde o begin at ao end). + depois efectua-se a execuo desse bloco (sinal /). Dica: Pode utilizar o comando show errors para verificar os erros do seu cdigo. Pode consultar mais detalhes sobre a criao de pacotes no manual.

Exerccio 4.1.: Definir o corpo do pacote. No esquecer de tratar casos em que h mais de um tuplo associado pesquisa (p.ex. vrios alunos com o mesmo nome, alunos inscritos em vrias disciplinas). No caso das funes devera retornar apenas o primeiro tuplo.