-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPratica9.sql
More file actions
334 lines (251 loc) · 9.65 KB
/
Pratica9.sql
File metadata and controls
334 lines (251 loc) · 9.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/*
Pedro Henrique Salmaze - 13783714
Daniela Cristina Bogni - 11218577
*/
-- 1)
-- Dados para teste
INSERT INTO Estrela(id_estrela, Nome, X, Y, Z) VALUES('HBNJK1345', 'Junior', 26, 6, 12);
INSERT INTO Estrela(id_estrela, Nome, X, Y, Z) VALUES('HBNJK1346', 'Delamaro', -2, 5, 0);
-- Função para calcular a distância entre duas estrelas
CREATE OR REPLACE FUNCTION Distancia_entre_estrelas(
estrela1 IN estrela%ROWTYPE,
estrela2 IN estrela%ROWTYPE
) RETURN NUMBER IS
v_distancia NUMBER;
BEGIN
v_distancia := SQRT(
POWER(estrela1.x - estrela2.x, 2) +
POWER(estrela1.y - estrela2.y, 2) +
POWER(estrela1.z - estrela2.z, 2)
);
RETURN v_distancia;
END;
CREATE OR REPLACE FUNCTION Distancia_entre_estrelas(
estrela1 IN estrela%ROWTYPE,
estrela2 IN estrela%ROWTYPE
) RETURN NUMBER IS
v_distancia NUMBER;
BEGIN
v_distancia := SQRT(
POWER(estrela1.x - estrela2.x, 2) +
POWER(estrela1.y - estrela2.y, 2) +
POWER(estrela1.z - estrela2.z, 2)
);
RETURN v_distancia;
END;
-- Programa PL/SQL para testar
DECLARE
v_estrela1 estrela%ROWTYPE;
v_estrela2 estrela%ROWTYPE;
v_nome_estrela1 estrela.Nome%TYPE;
v_nome_estrela2 estrela.Nome%TYPE;
v_resultado NUMBER;
BEGIN
v_nome_estrela1 := 'Junior';
v_nome_estrela2 := 'Delamaro';
SELECT * INTO v_estrela1 FROM ESTRELA WHERE Nome = v_nome_estrela1;
SELECT * INTO v_estrela2 FROM ESTRELA WHERE Nome = v_nome_estrela2;
v_resultado := Distancia_entre_estrelas(v_estrela1, v_estrela2);
dbms_output.put_line(v_resultado);
END;
-- 2)
-- Declaracao do pacote
-- Pacote acessavel por lideres
CREATE OR REPLACE PACKAGE Funcoes_Lider AS
e_Acesso_Negado EXCEPTION;
PROCEDURE Remover_Nacao (
lider_logado IN lider%ROWTYPE,
v_nacao_a_ser_removida IN nacao.nome%TYPE);
END Funcoes_Lider;
-- Corpo do pacote
CREATE OR REPLACE PACKAGE BODY Funcoes_Lider AS
-- Parametros: Lider logado e a nacao que deseja remover
PROCEDURE Remover_Nacao(
lider_logado IN lider%ROWTYPE,
v_nacao_a_ser_removida IN nacao.nome%TYPE) AS
v_lider_esperado lider.Cpi%TYPE;
v_faccao_lider faccao.nome%TYPE;
BEGIN
SELECT F.Lider INTO v_lider_esperado FROM
Nacao_Faccao NF JOIN Faccao F ON NF.Faccao = F.Nome
WHERE NF.Nacao = v_nacao_a_ser_removida;
SELECT F.Nome INTO v_faccao_lider FROM
Faccao F JOIN Lider L ON F.Lider = L.Cpi WHERE L.Nome = lider_logado.Nome;
IF lider_logado.Cpi = v_lider_esperado THEN
DELETE FROM NACAO_FACCAO WHERE Nacao = v_nacao_a_ser_removida AND Faccao = v_faccao_lider;
ELSE
RAISE e_Acesso_Negado;
END IF;
END;
END Funcoes_Lider;
-- Programa PL/SQL para testar
DECLARE
v_lider lider%ROWTYPE;
v_nacao_para_remocao nacao.nome%TYPE;
BEGIN
v_nacao_para_remocao := 'Sit id ipsam.';
SELECT * INTO v_lider FROM Lider WHERE Nome = 'Oliver';
Funcoes_Lider.Remover_Nacao(v_lider, v_nacao_para_remocao);
EXCEPTION
WHEN Funcoes_Lider.e_Acesso_Negado THEN dbms_output.put_line('Acesso negado');
END;
-- 3)
CREATE OR REPLACE PACKAGE Funcoes_Lider AS
e_Acesso_Negado EXCEPTION;
e_Federacao_Repetida EXCEPTION;
PROCEDURE Remover_Nacao (
lider_logado IN lider%ROWTYPE,
v_nacao_a_ser_removida IN nacao.nome%TYPE);
PROCEDURE Criar_Federacao(
lider_logado IN lider%ROWTYPE,
v_nome_federacao federacao.Nome%TYPE);
END Funcoes_Lider;
/
CREATE OR REPLACE PACKAGE BODY Funcoes_Lider AS
PROCEDURE Remover_Nacao(
lider_logado IN lider%ROWTYPE,
v_nacao_a_ser_removida IN nacao.nome%TYPE) AS
v_lider_esperado lider.Cpi%TYPE;
v_faccao_lider faccao.nome%TYPE;
BEGIN
SELECT F.Lider INTO v_lider_esperado FROM
Nacao_Faccao NF JOIN Faccao F ON NF.Faccao = F.Nome
WHERE NF.Nacao = v_nacao_a_ser_removida;
SELECT F.Nome INTO v_faccao_lider FROM
Faccao F JOIN Lider L ON F.Lider = L.Cpi WHERE L.Nome = lider_logado.Nome;
IF lider_logado.Cpi = v_lider_esperado THEN
DELETE FROM NACAO_FACCAO WHERE Nacao = v_nacao_a_ser_removida AND Faccao = v_faccao_lider;
ELSE
RAISE e_Acesso_Negado;
END IF;
END;
PROCEDURE Criar_Federacao(
lider_logado IN lider%ROWTYPE,
v_nome_federacao federacao.Nome%TYPE) AS
v_nacao_lider Lider.nacao%TYPE;
v_contagem_de_federacaoes NUMBER;
BEGIN
IF lider_logado.Cargo != 'COMANDANTE' THEN
dbms_output.put_line('Acesso negado');
END IF;
SELECt COUNT(*) INTO v_contagem_de_federacaoes FROM Federacao WHERE Nome = v_nome_federacao;
IF v_contagem_de_federacaoes != 0 THEN
dbms_output.put_line('Ja ha uma federacao com esse nome');
END IF;
INSERT INTO Federacao VALUES(v_nome_federacao, SYSDATE);
UPDATE Nacao SET federacao = v_nome_federacao WHERE nome = lider_logado.nacao;
END;
END Funcoes_Lider;
/
DECLARE
v_lider lider%ROWTYPE;
v_federacao_para_adicionar federacao.nome%TYPE;
BEGIN
v_federacao_para_adicionar := 'Benzoato';
SELECT * INTO v_lider FROM Lider WHERE Nome = 'Mathues';
Funcoes_Lider.Criar_Federacao(v_lider, v_federacao_para_adicionar);
EXCEPTION
WHEN Funcoes_Lider.e_Acesso_Negado THEN dbms_output.put_line('Acesso negado');
WHEN Funcoes_Lider.e_Federacao_Repetida THEN dbms_output.put_line('Ja existe um afederação com esse nome');
END;
-- Para testes
UPDATE Lider SET Cargo = 'COMANDANTE' WHERE Nome = 'Mathues';
SELECT * FROM FEDERACAO WHERE Nome = 'Benzoato';
-- 4)
CREATE OR REPLACE PACKAGE Funcoes_Cientista AS
-- Create
PROCEDURE Adicioar_Estrela(v_estrela IN estrela%ROWTYPE);
-- Read
PROCEDURE Ler_Por_Classificacao(v_cursor OUT SYS_REFCURSOR, v_classificacao estrela.classificacao%TYPE);
-- Delete
PROCEDURE Remover_Estrela_Por_ID(v_id_estrela IN estrela.id_estrela%TYPE);
PROCEDURE Remover_Estrela_Por_Nome(v_nome_estrela IN estrela.nome%TYPE);
-- Update
PROCEDURE Atualizat_Massa_Estrela(v_id_estrela IN estrela.id_estrela%TYPE, v_nova_massa IN NUMBER);
PROCEDURE Atualizat_Classficacao_Estrela(v_id_estrela IN estrela.id_estrela%TYPE, v_nova_classificacao IN estrela.classificacao%TYPE);
-- Relatorios
PROCEDURE Info_Estrelas_e_seus_Sistemas(c_estrelas OUT SYS_REFCURSOR);
PROCEDURE Info_Planetas(c_planetas OUT SYS_REFCURSOR);
END Funcoes_Cientista;
/
CREATE OR REPLACE PACKAGE BODY Funcoes_Cientista AS
PROCEDURE Adicioar_Estrela(v_estrela IN estrela%ROWTYPE) AS
BEGIN
INSERT INTO Estrela VALUES v_estrela;
-- Execao se ja houver uma estrela com esse nome
END;
PROCEDURE Ler_Por_Classificacao(v_cursor OUT SYS_REFCURSOR, v_classificacao estrela.classificacao%TYPE) AS
BEGIN
OPEN v_cursor FOR SELECT *
FROM Estrela WHERE Classificacao = v_classificacao;
END;
PROCEDURE Remover_Estrela_Por_ID(v_id_estrela IN estrela.id_estrela%TYPE) AS
BEGIN
DELETE FROM Estrela WHERE id_estrela = v_id_estrela;
END;
PROCEDURE Remover_Estrela_Por_Nome(v_nome_estrela IN estrela.nome%TYPE) AS
BEGIN
DELETE FROM Estrela WHERE Nome = v_nome_estrela;
END;
PROCEDURE Atualizat_Massa_Estrela(v_id_estrela IN estrela.id_estrela%TYPE, v_nova_massa IN NUMBER) AS
BEGIN
UPDATE Estrela SET Massa = v_nova_massa WHERE Id_Estrela = v_id_estrela;
END;
PROCEDURE Atualizat_Classficacao_Estrela(v_id_estrela IN estrela.id_estrela%TYPE, v_nova_classificacao IN estrela.classificacao%TYPE) AS
BEGIN
UPDATE Estrela SET Classificacao = v_nova_classificacao WHERE Id_Estrela = v_id_estrela;
END;
PROCEDURE Info_Estrelas_e_seus_Sistemas(c_estrelas OUT SYS_REFCURSOR) AS
BEGIN
OPEN c_estrelas FOR
SELECT E.Id_Estrela AS ID, E.Nome, E.Classificacao, E.Massa, S.Nome AS Sistema, E.X, E.Y, E.Z
FROM Estrela E
LEFT JOIN Sistema S ON E.Id_Estrela = S.Estrela;
END;
PROCEDURE Info_Planetas(c_planetas OUT SYS_REFCURSOR) AS
BEGIN
OPEN c_planetas FOR
SELECT * FROM Planeta;
END;
END Funcoes_Cientista;
/
-- PL/SQL simples apenas para testes
DECLARE
v_estrela Estrela%ROWTYPE;
v_planeta Planeta%ROWTYPE;
v_cursor SYS_REFCURSOR;
v_id_estrela Estrela.id_estrela%TYPE;
v_nova_massa NUMBER;
v_nova_classificacao Estrela.classificacao%TYPE;
BEGIN
v_estrela.id_estrela := 1;
v_estrela.nome := 'Estrela Teste';
v_estrela.classificacao := 'G';
v_estrela.massa := 1.0;
v_estrela.X := 1;
v_estrela.Y := 34;
v_estrela.Z := 16;
-- Adicionando uma nova estrela
Funcoes_Cientista.Adicioar_Estrela(v_estrela);
-- Lendo estrelas por classificação
Funcoes_Cientista.Ler_Por_Classificacao(v_cursor, 'G');
-- Processar os resultados do cursor v_cursor
v_id_estrela := 1;
v_nova_massa := 2.0;
Funcoes_Cientista.Atualizat_Massa_Estrela(v_id_estrela, v_nova_massa);
v_nova_classificacao := 'K';
Funcoes_Cientista.Atualizat_Classficacao_Estrela(v_id_estrela, v_nova_classificacao);
Funcoes_Cientista.Remover_Estrela_Por_ID(v_id_estrela);
Funcoes_Cientista.Remover_Estrela_Por_Nome('Estrela Teste');
-- Obtendo informações sobre estrelas e seus sistemas
Funcoes_Cientista.Info_Estrelas_e_seus_Sistemas(v_cursor);
-- Processar os resultados do cursor v_cursor
CLOSE v_cursor;
-- Obtendo informações sobre planetas
Funcoes_Cientista.Info_Planetas(v_cursor);
LOOP
FETCH v_cursor INTO v_planeta;
EXIT WHEN v_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_planeta.ID_Astro || ' ' || v_planeta.Massa);
END LOOP;
END;