Relatório Projecto de Base de Dados Parte 2 Turno: quinta-feira, 11:30 Grupo 25: André Gonçalves 64027 Rui Barradas 68239 Hélton Miranda 68477
1. Criação da base de dados De seguida vem escrito um script com as instruções necessárias para a base de dados, escolheu-se os tipos mais apropriados tais como, integer, varchar, numeric, date, time. Vem também definido as restrições de integridade correspondentes às primary key e foreign key patentes em cada tabela. create table Banda ( idb integer not null unique, nome varchar(255) not null, cidade varchar(255) not null, país varchar(255) not null, ano integer not null, primary key (idb)) create table Edicao ( idb integer not null, tituloe varchar(255) not null, ano integer not null, editora varchar(255) not null, primary key (idb, tituloe), foreign key (idb) references Banda on delete cascade on update cascade) create table Musica ( idb integer not null, titulom varchar(255) not null, duracao numeric(2,2) not null, primary key (idb, titulom), foreign key (idb) references Banda on delete cascade on update cascade) create table Album ( idb integer not null, tituloe varchar(255) not null, primary key (idb, tituloe), foreign key (idb, tituloe) references Edicao on delete cascade on update cascade)
create table Faixa ( idb integer not null, tituloe varchar(255) not null, numero integer not null, titulom varchar(255) not null, primary key (idb, tituloe, numero), foreign key (idb, tituloe) references Album on delete cascade on update cascade, foreign key (idb, titulom) references Musica on delete cascade on update cascade) create table Single ( idb integer not null, tituloe varchar(255) not null, titulom varchar(255) not null, primary key (idb, tituloe), foreign key (idb, tituloe) references Edicao on delete cascade on update cascade, foreign key (idb, titulom) references Musica on delete cascade on update cascade) create table Concerto ( idb integer not null, data date not null, hora time not null, local varchar(255) not null, primary key (idb, data, hora), foreign key (idb) references Banda on delete cascade on update cascade) create table Original ( idb integer not null, titulom varchar(255) not null, primary key (idb, titulom), foreign key (idb, titulom) references Musica on delete cascade on update cascade)
create table Live ( idb integer not null, titulom varchar(255) not null, data date not null, hora time not null, titulomo varchar(255) not null, primary key (idb, titulom), foreign key (idb, titulom) references Musica on delete cascade on update cascade, foreign key (idb, data, hora) references Concerto on delete cascade on update cascade, foreign key (idb, titulomo) references Original on delete cascade on update cascade) 2. Consultas SQL Nesta secção é apresentada uma consulta por cada alinea. a) select Banda.nome,Edicao.tituloE,count(numero),sum(duracao) from Faixa,Edicao,Banda,Musica where Faixa.idB = Banda.idB and Faixa.idB = Musica.idB and Faixa.idB = Edicao.idB and Musica.tituloM = Faixa.tituloM and Edicao.ano = 2011 and Edicao.tituloE = Faixa.tituloE group by Banda.idB,Banda.nome,Edicao.tituloE; b) select Banda.nome,Faixa.tituloE,count(numero) from Faixa,Single,Banda where Faixa.Idb = Single.Idb and Faixa.tituloM = Single.tituloM and Banda.Idb = Faixa.Idb group by Banda.idB,Banda.nome,Faixa.tituloE having count(numero) >= all (select count(numero) from Faixa,Single,Banda where Banda.idB = Faixa.idB
and Single.idB = Faixa.idB and Faixa.tituloM = Single.tituloM group by Banda.idB,Banda.nome,Faixa.tituloE); c) (select nome, tituloe from Banda natural join Faixa) except (select nome, tituloe from Banda natural join Faixa natural join Live) d) select idb,nome,tituloe from Banda natural inner join (select idb,tituloe from (Live natural inner join Faixa) as newalbum where not exists ((select idb,titulom from Faixa where newalbum.idb = Faixa.idB and newalbum.tituloe = Faixa.tituloE) except (select idb,titulom from live where Live.idB = newalbum.idb))) as Albuns_Live group by idb,nome,tituloe; 3. Restrições de integridade Teve-se em conta os mecanismos suportados pelo sistema Postgres, exemplo disso foi a utilização do trigger em vez de assertion, o que dificultou a resolução da implementação das seguintes restrições de integridade. a) Só pode haver uma versão live da mesma música original create table Live ( idb integer, titulom varchar(255), data date not null, hora time not null, titulomo varchar(255) not null,
primary key (idb, titulom), foreign key (idb, titulom) references Musica, foreign key (idb, data, hora) references Concerto, foreign key (idb, titulomo) references Original, unique(idb, data, hora, titulomo)) b) Todos os títulos de um album têm de ser o título de uma das faixas com uma faixa já publicada como single /***************TRIGGERS*********************************************/ /*******VERIFICA O ALBUM CRIADO************************/ create or replace function verifica_titulo_album() returns trigger as $$ declare id banda.idb%type; musica single.titulom%type; begin end select banda.idb into id from banda where banda.idb = new.idb; select single.titulom into musica from single where new.idb = single.idb and single.titulom = new.tituloe; if(id is null or musica is null) then delete from edicao where edicao.idb = new.idb and edicao.tituloe = new.tituloe; raise exception 'O titulo do album % deve ser o titulo de uma música já existente',new.tituloe; end if; insert into Faixa values (new.idb,new.tituloe,1,new.tituloe); return new; $$ language plpgsql; create trigger verifica_titulo_album_trigger after insert on Album for each row execute procedure verifica_titulo_album(); /********************************************************************/
create or replace function verifica_update_album() returns trigger as $$ begin raise exception 'Não é possivel actualizar um album, dada a complexidade da operação' ; end $$ language plpgsql; create trigger verifica_update_album_trigger before update on Album for each row execute procedure verifica_update_album(); /**********VERIFICA O SINGLE*****************************************/ create or replace function verifica_apagar_single() returns trigger as $$ declare titulo album.tituloe%type; begin select album.tituloe into titulo from album where idb = old.idb and tituloe = old.titulom; if(titulo is not null) then raise exception 'Não se pode apagar este single que é titulo de um álbum, primeiro apague o album %',titulo; end end if; return old; $$ language plpgsql; create trigger verifica_apagar_single_trigger after delete on Single for each row execute procedure verifica_apagar_single(); /********************************************************************/ create or replace function verifica_update_single() returns trigger as $$ begin raise exception 'Não se pode actualizar simplesmente um single, é muito complexo';
end $$ language plpgsql; create trigger verifica_update_single_trigger before update on Single for each row execute procedure verifica_update_single(); /********************************************************************/ 4. Desenvolvimento da aplicação A aplicação pode ser acedida através do url: //web.ist.utl.pt/ist168477/home.html home.html( homepage )
bandas.php <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $sql = "SELECT * FROM Banda;"; $result = pg_query($sql) or die('error: '. pg_last_error()); echo("tabela das Bandas:"); echo('<table border="10">'); echo("<tr><td>id_banda</td><td>nome</td><td>cidade</td><td>pais</td><td>ano de Criacao</td></tr>"); while ($row = pg_fetch_assoc($result)) { echo("<tr><td>"); echo($row["idb"]); echo("</td><td>"); echo($row["nome"]); echo("</td><td>"); echo($row["cidade"]); echo("</td><td>"); echo($row["pais"]); echo("</td><td>"); echo($row["ano"]); echo("</td></tr>"); } echo("</table>"); $result = pg_free_result($result) or die('error: '. pg_last_error()); pg_close($connection);?> </body> </html>
seleccionabanda.php <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); echo("<h1><b>seleccao de uma Banda</b></h1>"); echo("<hr>"); echo("<p><b>para criar um album deve executar os seguintes passos:</b></p>"); echo("<p>1 - Escolher uma Banda</p>"); $sql = "SELECT idb,nome FROM Banda;"; $result = pg_query($sql) or die('error: '. pg_last_error()); $aux = pg_query($sql) or die('error: '. pg_last_error()); echo("tabela das Bandas disponiveis:"); echo('<table border="2">'); echo("<tr><td>id_banda</td><td>nome</td></tr>"); while ($row = pg_fetch_assoc($result)) { echo("<tr><td>"); echo($row["idb"]); echo("</td><td>"); echo($row["nome"]); echo("</td></tr>"); } echo("</table>"); echo("<form action='criaralbum.php' method='post' name='bandas'>"); echo("<p>seleccione a banda: <select name='id_banda'>"); while($row = pg_fetch_assoc($aux)) { echo("<option value={$row['idb']}>".$row["idb"]."</option>"); } echo("</select> </p>"); echo("<input type='submit' name='sub' value='continuar'>"); echo("</form>"); $result = pg_free_result($result) or die('error: '. pg_last_error()); $aux = pg_free_result($aux) or die('error: '. pg_last_error()); pg_close($connection);?> </body> </html>
criaralbum.php <?php session_start();?> <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $id_banda = $_REQUEST["id_banda"]; $idb = "idb"; $_SESSION['idb'] = $id_banda; echo("<h1><b>criacao de um Album</b></h1>"); echo("<hr>"); $obtem_banda = "SELECT nome FROM Banda where idb = '$id_banda' ;" ; $nome_banda = pg_query($obtem_banda) or die('error: '. pg_last_error()); $row = pg_fetch_assoc($nome_banda); $_SESSION['nome'] = $row["nome"]; $nome_banda_aux = $row["nome"]; $sql = "SELECT tituloe,titulom FROM Single where idb = '$id_banda' ;"; $result = pg_query($sql) or die('error: '. pg_last_error()); $aux = pg_query($sql) or die('error: '. pg_last_error()); echo("musicas dos Singles da Banda $nome_banda_aux :"); echo('<table border="2">'); echo("<tr><td>titulo do Single</td><td>Musica</td></tr>"); while ($row = pg_fetch_assoc($result)) { echo("<tr><td>"); echo($row["tituloe"]); echo("</td><td>"); echo($row["titulom"]); echo("</td></tr>"); } echo("</table>"); echo("<p>2 - Seleccione o nome de uma das musicas para o nome do álbum </p>"); echo("<form action='inseriralbumbd.php' name='criaralbum' method='post'>"); echo("<p>seleccione o titulo do album: <select name='titulo_album'>");
while($row = pg_fetch_assoc($aux)) { echo("<option value={$row['titulom']}>".$row["titulom"]."</option>"); } echo("</select> </p>"); echo("<p>3 - Preencher os campos em branco com os dados necessários para a criacao de um album </p>"); echo("<p>nome da Editora:<input type='text' name='editora'></p>"); echo("<p>ano de edicao : <input type='text' name='ano'> </p>"); echo("<p>4 - Clicar o botao continuar</p>"); echo("<input type='submit' name='album' value='ir para seleccionar Faixas'>"); echo("</form>"); $result = pg_free_result($result) or die('error: '. pg_last_error()); $aux = pg_free_result($aux) or die('error: '. pg_last_error()); $nome_banda = pg_free_result($nome_banda) or die('error: '. pg_last_error()); pg_close($connection);?> </body> </html> inseriralbumbd.php <?php session_start();?> <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $idb = $_SESSION['idb']; $nome_album = $_REQUEST["titulo_album"]; $editora = $_REQUEST["editora"]; $ano = $_REQUEST["ano"]; $int_ano = intval($ano); if($editora!= '' and int_ano >= 0000 and int_ano <= 9999) { com os dados preenchidos //Inserir a edição criada na base de dados, de acordo
$insert_album = "INSERT INTO EDICAO VALUES('$idb', '$nome_album', '$int_ano','$editora');"; $result_insert = pg_query($insert_album) or die('error: '. pg_last_error()); VALUES('$idb', '$nome_album');"; die('error: '. pg_last_error()); $insert_album = "INSERT INTO ALBUM $result_insert = pg_query($insert_album) or $_SESSION['n_faixa'] = 2; //inicialização do numero da faixa do album $_SESSION['tituloe'] = $nome_album; echo("<h1><b>insercao do Album</b></h1>"); echo("<hr>"); sucesso</p>"); value='adicionar Faixas'>"); echo("<p>album $nome_album criado com echo("<form action='menumusica.php'>"); echo("<input type='submit' name='menumusica' echo("</form>"); correctamente"); } else { } echo("erro: Algum campo nao foi preenchido pg_close($connection);?> </body> </html> menumusica.php <?php session_start();?> <html> <p><h1>menu da Musica:</h1></p> <hr> <p>menu de opcoes:</p> <form action="seleccionarfaixa.php">
</body> </html> <input type="submit" name="seleccionarfaixas" value="seleccionar uma Faixa"> </form> <form action="criarmusica.php"> <input type="submit" name="criarmusica" value="criar uma Musica"> </form> seleccionarfaixa.php <?php session_start();?> <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $idb = $_SESSION['idb']; $nome_banda = $_SESSION['nome']; $sql = "SELECT * FROM Musica where idb = '$idb';"; pg_last_error()); pg_last_error()); $result = pg_query($sql) or die('error: '. $result2 = pg_query($sql) or die('error: '. echo("musicas da Banda $nome_banda :"); echo('<table border="2">'); Musica</td><td>Duracao</td></tr>"); echo("<tr><td>titulo da while ($row = pg_fetch_assoc($result)) {
echo("<tr><td>"); echo($row["titulom"]); echo("</td><td>"); echo($row["duracao"]); echo("</td></tr>"); } echo("</table>"); echo("<form action='inserefaixabd.php' method='post' name='musicas'>"); echo("<p>seleccione a musica: <select name='musica'>"); while($row = pg_fetch_assoc($result2)) { echo("<option value={$row['titulom']}>".$row["titulom"]."</option>"); } echo("</select> </p>"); echo("<input type='submit' name='sub' value='inserir'>"); echo("</form>"); pg_last_error()); pg_last_error()); $result = pg_free_result($result) or die('error: '. $result2 = pg_free_result($result2) or die('error: '. pg_close($connection);?> </body> </html> inserefaixabd.php <?php session_start();?> <html> <h1><b>insercao de uma Faixa na Base de Dados</b></h1> <hr> <body> <?php
$user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $nome_musica = $_REQUEST["musica"]; $id_banda = $_SESSION['idb']; $titulo_album = $_SESSION['tituloe']; $faixa = $_SESSION['n_faixa']; $sql = "INSERT INTO FAIXA VALUES('$id_banda','$titulo_album','$faixa','$nome_musica');"; $result = pg_query($sql) or die('error: '. pg_last_error()); para a pŕoxima musica $_SESSION['n_faixa']++; //incremento o numero da faixa pg_last_error()); $result = pg_free_result($result) or die('error: '. pg_close($connection);?> <p>se quiser inserir mais fixas clique no botao +:</p> value="+"> <form action="menumusica.php"> <input type="submit" name="mais_faixas" </form> <p>se tiver terminado de inserir todas as faixas clique em Concluir</p> value="concluir"> </body> </html> <form action="visualizarnovoalbum.php"> <input type="submit" name="concluido" </form> criarmusica.php <?php session_start();?> <html> <body> <p><h1>criacao de uma Musica</h1></p> <hr>
name='criarmusica'> name='nome_musica'> </p> name='duracao_musica'> </p> <form action='inseremusicabd.php' <p> "Nome da nova musica: <input type='text' <p> "Duracao da nova musica: <input type='time' name='criarmusica' value='criar Nova Musica'> </form> <input type='submit' </body> </html> inseremusicabd.php <?php session_start();?> <html> <body> <h1><b>criacao de uma Musica</b></h1> <hr> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $nome_musica = $_REQUEST["nome_musica"]; $duracao = $_REQUEST["duracao_musica"]; $id_banda = $_SESSION['idb']; $faixa = $_SESSION['n_faixa']; $titulo_album = $_SESSION['tituloe']; $sql1 = "INSERT INTO MUSICA VALUES('$id_banda', '$nome_musica', '00:$duracao');"; $sql2 = "INSERT INTO FAIXA VALUES('$id_banda', '$titulo_album', '$faixa', '$nome_musica');"; $result1 = pg_query($sql1) or die('error: '. pg_last_error());
$result2 = pg_query($sql2) or die('error: '. pg_last_error()); para a pŕoxima musica $_SESSION['n_faixa']++; //incremento o numero da faixa pg_last_error()); pg_last_error()); $result1 = pg_free_result($result1) or die('error: '. $result2 = pg_free_result($result2) or die('error: '.?> pg_close($connection); <p>se quiser inserir mais fixas clique no botao +:</p> value="+"> <form action="menumusica.php"> <input type="submit" name="mais_faixas" </form> <p>se tiver terminado de inserir todas as faixas clique em Concluir</p> value="concluir"> <form action="visualizarnovoalbum.php"> <input type="submit" name="concluido" </form> </body> </html> visualizarnovoalbum.php <?php session_start();?> <html> <body> <?php $user = "ist168477"; $host = "db.ist.utl.pt"; $port = 5432; $password = "vpbo0929"; $dbname = $user; $connection = pg_connect("host=$host port=$port user=$user password=$password dbname=$dbname") or die(pg_last_error()); $id_banda = $_SESSION['idb']; $nome_album = $_SESSION['tituloe'];
echo("<p><h1>album criado: $nome_album </h1></p>"); echo("<hr>"); $sql = "SELECT * FROM FAIXA WHERE FAIXA.idB = '$id_banda' and FAIXA.tituloE = '$nome_album';"; $result = pg_query($sql) or die('error: '. pg_last_error()); echo("tabela das Faixas do album $nome_album :"); echo('<table border="10">'); echo("<tr><td>id_banda</td><td>titulo do Album</td><td>Numero da Faixa</td><td>Titulo da Musica</td></tr>"); while ($row = pg_fetch_assoc($result)) { } echo("</table>"); echo("<tr><td>"); echo($row["idb"]); echo("</td><td>"); echo($row["tituloe"]); echo("</td><td>"); echo($row["numero"]); echo("</td><td>"); echo($row["titulom"]); echo("</td></tr>"); pg_last_error()); $result = pg_free_result($result) or die('error: '. pg_close($connection);?> HomePage"> <form action="home.html"> <input type="submit" name="homepage" value="ir para
</body> </html> </form>