520 likes | 645 Views
Àlgebra e SQL. Pedro Nogueira Ramos (Pedro.Ramos@iscte.pt) DCTI / ISCTE. Álgebra Relacional (Codd, 1972).
E N D
Àlgebra e SQL Pedro Nogueira Ramos (Pedro.Ramos@iscte.pt) DCTI / ISCTE Pedro Ramos, DCTI/ISCTE
Álgebra Relacional(Codd, 1972) No Modelo relacional a informação é representada através de relações (ou tabelas). A Álgebra Relacional é um conjunto de operações formais que operam sobre relações. No essencial a álgebra relacional corresponde à álgebra de conjuntos, ou seja, é definida com base nos operadores de Intersecção, Produto Cartesiano e União. Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Tipos de Operações Todas as operações produzem como resultado outras relações. Tipos de operações: Binárias (operam sobre conjuntos) União Produto Cartesiano (e Join) Unárias (operam apenas sobre um conjunto) Projecção Selecção Relações compatíveis – mesmo grau (número de atributos) e atributos idênticos (i.e., tipos de dados compatíveis). Pedro Ramos, DCTI/ISCTE
Álgebra Relacional União Apenas pode ser efectuada entre relações compatíveis. R S = {t: t R ou t S}, em que t representa um tuplo (linha) As linhas duplicadas apenas são seleccionadas caso se indique explicitamente para não as retirar (UNION ALL) Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Produto Cartesiano R X S = {t1.t2: t1 R e t2 S} Cliente X = Localidade Únicas linhas coerentes: Join Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Join INNER JOIN: Produto Cartesiano, em que apenas são seleccionados tuplos nos quais os valores dos atributos comuns são idênticos. Normalmente o atributo comum não é repetido. OUTER LEFT JOIN: resultado do NATURAL JOIN união com os tuplos da relação à esquerda que não ”cruzaram” (não existe nenhum tuplo na relação à direita que tenha o mesmo valor no atributo comum) com a relação à direita. OUTER RIGHT JOIN: resultado NATURAL JOIN união com os tuplos da relação à direita que não ”cruzaram” com a relação à esquerda. Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Exemplos de Join Cliente Natural Join (Inner Join) Outer Left Join X Localidade Outer Right Join Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Projecção Ai, Aj, … , Am (R) ={< t(Ai), t(Aj), …, t(Am) >: t R} em que R(A1, A2, …, An) é a relação projectada; Ai, Aj, …, Am são atributos da projecção; i, j, …, m são inteiros compreendidos no intervalo 1 … n . (A) R R As linhas duplicadas apenas são removidas caso se indique explicitamente (DISTINCT) Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Selecção F (R) ={t: t R e t satisfaz F}em que em que F é uma fórmula envolvendo atributos e operadores lógicos (devolvem verdade ou falso) como operandos. (A=a) R R Pedro Ramos, DCTI/ISCTE
Álgebra Relacional Exemplos de Interrogações 1 ”Listar o nome e nacionalidade dos autores de nacionalidade Portuguesa e Brasileira” nome, nacionalidade (nacionalidade =”Portuguesa” or nacionalidade =”Brasileira” (Autor)) 2 ”Listar os títulos dos livros do Gabriel Garcia Marquez” titulo (nome Like ”Gabriel*” ((Autor X Autoria) X Livro)) 3 ”Listar o nome dos autores, indicando os títulos dos seus livros” a) nome, titulo ((Autor X Autoria) X Livro) incorrecto, não selecciona os autores sem livros b) nome, titulo (Autor X OUTER LEFT JOIN (Autoria X Livro) Pedro Ramos, DCTI/ISCTE
SQL - Índice Domínios e Tipos de Dados Tabelas Índices DML (Data Manipulation Language) Prepared Statements Stored Procedures Triggers SELECT Cláusula SELECT Cláusula FROM Joins Cláusula WHERE Cláusulas GROUP BY, HAVING e funções de agregação UNION UPDATE DELETE INSERT Optimização de Querys Views Pedro Ramos, DCTI/ISCTE
Linguagem SQL Norma ANSI criada em 1986 (revista em 1989 e 1992). A linguagem SQL tem duas vertentes: DDL (Data Definition Language) e DML (Data Manipulation Language). Na vertente DDL o SQL possui um conjunto de comandos para criação e alteração de tabelas, chaves estrangeiras, regras de integridade referencial e views. A vertente DML é uma implementação da Álgebra Relacional, e.g., permite efectuar interrogações a uma base de dados, bem como alterar, anular ou inserir registos em tabelas. Ao longo do texto será apresentado o SQL do Adaptive Server Anywhere 6.0 da Sybase. Pedro Ramos, DCTI/ISCTE
SQL Domínios e Tipos de Dados (DDL) Em SQL é possível especificar o domínio (tipo de dados) de um atributo. Através da cláusula DOMAIN é possível definir um domínio genérico ao qual podem ser atribuídos vários atributos. O seguinte comando define o domínio morada: CREATE Datatype dm_morada VARCHAR(100); Alguns Tipos de Dados Texto Char [(n)] (equivalente a Varchar (n)) Long Varchar - infinitos caracteres Text – eq. a Long Varchar mas admite NULL Boleano Bit [0, 1] Data Date Time TimeStamp (data e hora) Número Tinyint [0 – 255] Smallint [-+ 32,767] ou UNSIGNED [0 - 65535] Integer [-+ 2,147,483,6479] Double [ grande] Decimal (inteiros[, decimais]) Pedro Ramos, DCTI/ISCTE
SQL Tabelas (DDL) (I) Comando para criar uma tabela: CREATE TABLEnome databela ( definição das colunas, restrições de integridade) CREATE Datatype dm_morada VARCHAR(100); CREATE TABLE Cliente ( cod_cliente INTEGER NOT NULL, bi INTEGER NOT NULL, nome VARCHAR(100), morada dm_morada, CONSTRAINT prim_key PRIMARY KEY (cod_cliente), CONSTRAINT cand_key UNIQUE (bi)); Chave alternativa Pedro Ramos, DCTI/ISCTE
SQL Tabelas (II) CREATE TABLE Factura ( num_factura INTEGER NOT NULL, data DATE NOT NULL, valor DECIMAL(10,2) NOT NULL, cod_cliente INTEGER NOT NULL, CONSTRAINT prim_key PRIMARY KEY (num_factura), CONSTRAINT for_key_cliente FOREIGN KEY (cod_cliente) REFERENCES Cliente (cod_cliente) ON UPDATE CASCADE ON DELETE RESTRICT); CREATE TABLE Produto ( cod_produtoINTEGER NOT NULL, tipo CHAR(2)DEFAULT 'MP‘CHECK (tipo IN ('MP','PA')) NOT NULL, DesignaçãoVARCHAR(100), CONSTRAINTprim_key PRIMARY KEY (cod_produto)); Chave Estrangeira Valor por omissão Restrições Pedro Ramos, DCTI/ISCTE
SQL Tabelas (III) CREATE TABLE Item ( num_factura INTEGER NOT NULL, num_item INTEGER CHECK (num_item between 1 and 10) NOT NULL, quantidade INTEGER CHECK (quantidade > 0) NOT NULL, valor DECIMAL (4,2) NOT NULL, cod_produto INTEGER NOT NULL, CONSTRAINT prim_key PRIMARY KEY (num_factura, num_item), CONSTRAINT for_key_factura FOREIGN KEY (num_factura) REFERENCES Factura (num_factura) ON UPDATECASCADE ON DELETE CASCADE, CONSTRAINT for_key_produto FOREIGN KEY (cod_produto) REFERENCES Produto (cod_produto) ON UPDATE CASCADE ON DELETE RESTRICT); Restrições Pedro Ramos, DCTI/ISCTE
SQL Tabelas (IV) Comando para alterar uma tabela: ALTER TABLEnome databela alterações ALTER TABLE cliente ADD COLUMN telefone VARCHAR (10) DROP COLUMN bi; Comando para alterar uma tabela: DROP TABLEnome databela Nota: É conveniente ter um ficheiro com a definição completa da base de dados. Esse ficheiro pode ser executado sempre que seja necessário reconstruir a base de dados. O uso sistemático dos comandos ALTER e DROP TABLE pode dificultar a reconstrução da base de dados. Pedro Ramos, DCTI/ISCTE
SQL Índices Comando para criar um índice tabela: CREATE [UNIQUE] INDEXnome índice ON nome tabela (nome coluna [ASC | DESC]) create unique index Index_Key on Medicamentos_Receita ( Codigo ASC, ID_Receita ASC ); Pedro Ramos, DCTI/ISCTE
SQL DML Linguagem para Manipulação de Dados SELECT Cláusula SELECT Cláusula FROM Joins Cláusula WHERE Cláusulas GROUP BY, HAVING e funções de agregação UNION UPDATE DELETE INSERT Optimização de Querys Views Pedro Ramos, DCTI/ISCTE
SQL Comando SELECT Um comando SQL típico para selecção de linhas obedece à seguinte estrutura (em que a cláusula SELECT corresponde à projecção, a cláusula FROM ao produto cartesiano e a cláusula WHERE à selecção): SELECTcampos a seleccionar FROMtabelas onde constam os campos indicados em Select WHEREexpressão lógica que indica quais as linhas que pretendemos seleccionar ORDER BYcampo pelo qual a listagem virá ordenada; Lista o nome e morada de uma tabela de clientes, mas apenas os clientes cujo código postal seja 1300 (ordenado por nome) SELECT Nome, Morada FROM Cliente WHERE Cod_Postal = 1300 ORDER BY Nome; Pedro Ramos, DCTI/ISCTE
SQL Nota É importante notar que qualquer comando SELECT devolve uma tabela (um conjunto de colunas e linhas). Sempre que, no contexto da sintaxe da linguagem SQL for referida uma tabela, ela deve ser interpretada no sentido mais lato: uma tabela original (definida no esquema relacional) ou o resultado de um comando SELECT. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula SELECT (I) Qualquer expressão sintacticamente válida pode ser argumento da cláusula SELECT. Por exemplo, os dois seguintes comandos são válidos: SELECT Produto, Quantidade * Preço FROM Item;(devolve duas colunas em que a segunda corresponde ao produto das colunas quantidade e preço); SELECT ‘teste’ FROM Item;(se a tabela item tiver 20 linhas, o comando devolve 20 vezes a palavra teste). Podem ser atribuídos aliases (sinónimos) às colunas. Por exemplo o comando anterior poderia ser escrito da seguinte forma (permite dar um nome – Total - à segunda coluna devolvida): SELECT Produto, Quantidade * Preço AS Total FROM Item; Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula SELECT (II) Caso pretendamos visualizar todos os campos de uma tabela, como alternativa a enumera-los todos, pode-se usar a constante *: SELECT * FROM Item; Caso pretendamos eliminar duplicados na listagem obtida, utiliza-se a cláusula DISTINCT (elimina linhas duplicadas) SELECT DISTINCT CodPostal FROM Aluno; (devolve os códigos postais existentes) Caso se pretenda listar dois atributos com o mesmo nome (correspondentes a duas tabelas referidas na cláusula FROM) é necessário preceder o nome do campo pelo nome da tabela de onde ele é originário. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula SELECT (III) Caso pretendamos apenas visualizar algumas linhas de uma tabela: SELECT FIRST * FROM Item; SELECT TOP 3 * FROM Item; Caso pretendamos armazenar o resultado em variáveis (apenas quando o comando apenas devolve uma linha) SELECT Max(Quantidade) INTO Maximo FROM ITEM; A cláusula INTO apenas se justifica quando o SQL é utilizado dentro de outra linguagem de programação (Java, C, Visual Basic, etc.) ou em Stored Procedures (ver mais adiante). Na cláusula INTO podem-se referir várias variáveis (o mesmo número das expressões da cláusula SELECT). Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula FROM (I) Na cláusula FROM indicam-se os nomes das tabelas envolvidas na interrogação, separadas por vírgulas. Quando existe mais que uma tabela o SQL executa automaticamente um produto cartesiano entre as tabelas. Por exemplo, o seguinte comando executa um produto cartesiano entre as tabelas Cliente e Localidade, devolvendo todos os campos (das duas tabelas): SELECT * FROM Cliente, Localidade; Caso queiramos obter um JOIN é necessário explicitar a forma como o pretendemos obter, por exemplo: SELECT * FROM Cliente INNER JOIN Localidade; SELECT * FROM Cliente LEFT OUTER JOIN Localidade; Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula FROM (II) Á semelhança dos sinónimos dos atributos, é possível atribuir aliases às tabelas (os sinónimos nas tabelas são relevantes nas subquerys, analisadas mais adiante): Select * From Cliente AS Cliente_Empresa; Existe uma tabela de sistema que apenas contém uma linha denominada DUMMY. Ela pode ser utilizada quando pretendemos listar uma expressão que não é obtida a partir de nenhuma tabela. SELECT COS(1) FROM DUMMY; Devolve o cosseno de 1 Pedro Ramos, DCTI/ISCTE
SQL SELECT – JOINS (I) Tipos de JOINS Key Join SELECT * FROM Cliente KEY JOIN Localidade; Critério: chave estrangeira. Apenas funciona se existir uma (e apenas uma) chave estrangeira a ligar as duas tabelas. Natural Join SELECT * FROM Cliente NATURAL JOIN Localidade; Critério: atributos com o mesmo nome. Apenas funciona se existir pelo menos um atributo com o mesmo nome e tipo de dados compatíveis. Join com Comparações SELECT * FROM Cliente JOIN Localidade ON Cliente.Cod_Postal = Localidade.Cod_Postal; Critério: indicado explicitamente no comando através do ON. É o mais flexível. Pedro Ramos, DCTI/ISCTE
SQL SELECT – JOINS (II) INNER, LEFT OUTER e RIGHT OUTER JOIN Podem ser utilizados nos Key, Natural e ON Join. Quando nada é indicado é efectuado um INNER Join. SELECT * FROM Cliente NATURAL INNER JOIN Localidade; SELECT * FROM Cliente NATURAL LEFT OUTER JOIN Localidade; SELECT * FROM Cliente KEY RIGHT OUTER JOIN Localidade; SELECT * FROM Cliente LEFT OUTER JOIN Localidade ON Cliente.Cod_Postal = Localidade.Cod_Postal; Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula WHERE (I) Na cláusula WHERE pode constar qualquer expressão lógica. A expressão é avaliada linha a linha, isto é, para cada linha o SQL avalia o valor da expressão e, caso seja verdadeira, devolve a linha. SELECT * FROM Cliente Where CodPostal > 1000 AND CodPostal < 2000; SELECT * FROM Cliente Where (CodPostal > 1000 AND CodPostal < 2000) OR CodPostal = 3000; Select * FROM CodPostal WHERE 1 = 1; (devolve todos os registos) Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula WHERE (II) Os principais operadores utilizados na cláusula WHERE são: =, <, >, >=, <=, <>, AND, OR, NOT, IN, LIKE, BETWEEN e ISNULL. O operador IN é verdadeiro quando um elemento faz parte de um conjunto. O operador permite a utilização de wildcards.O operador ISNULL permite lidar com valores NULL. Alguns exemplos: SELECT * FROM CLIENTE WHERE CodPostal BETWEEN 1000,2000; SELECT * FROM CLIENTE WHERE Nome LIKE ‘João%’(todos os clientes começados por João) SELECT * FROM Cliente WHERE Nacionalidade IN (‘Portugal’, ‘Brasil’);(todos os clientes portugueses ou brasileiros) SELECT * FROM Cliente WHERE Nacionalidade NOT IN (‘Portugal’, ‘Brasil’); (todos os clientes excepto os portugueses e brasileiros) SELECT * FROM Cliente WHERE Nacionalidade IS NOT NULL;(todos os clientes com nacionalidade conhecida) Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusula WHERE (III) A cláusula WHERE pode ser utilizada para produzir joins. Os dois seguintes comandos produzem o mesmo resultado (o 1º é mais eficiente devido às optimizações do SGBD). SELECT * FROM Cliente INNER JOIN Localidade ON Cliente.Cod_Postal = Localidade.Cod_Postal; SELECT * FROM Cliente, Localidade WHERE Cliente.Cod_Postal = Localidade.Cod_Postal; Os seguinte comando produz um INNER JOIN apesar de estar indicado um LEFT JOIN (primeiro é efectuado o LEFT JOIN, mas posteriormente o SGBD apenas considera as linhas em que existe igualdade entre as chaves). SELECT * FROM Cliente NATURAL LEFT OUTER JOIN Localidade WHERE Cliente.Cod_Postal = Localidade.Cod_Postal; Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusulas GROUP BY e HAVING e Funções de Agregação (I) Recorrendo apenas às cláusulas anteriores não é possível, por exemplo, efectuar certas operações estatísticas (somatórios, médias, etc.). Tal acontece porque as operações de agregação (que envolvem vários registos) não poderem ser calculadas linha a linha. Por exemplo, o comando para listar os códigos postais associados a mais do que dois clientes não pode ser efectuado tal como de seguida se apresenta: SELECT CodPostal FROM Cliente WHERE COUNT(CodPostal) > 2 O comando é incorrecto porque a cláusula WHERE é testada linha a linha e, numa linha não é possível obter o total de códigos postais. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusulas GROUP BY e HAVING e Funções de Agregação (II) As cláusulas GROUP BY e HAVING permitem manipular valores agregados. A cláusula GROUP BY permite a definição de grupos. A cláusula HAVING é equivalente à cláusula WHERE só que o seu argumento são expressões lógicas relativas aos agrupamentos criados pela cláusula GROUP BY. O exemplo anterior encontra-se bem formulado com o seguinte comando: SELECT CodPostal FROM Cliente GROUP BY CodPostal HAVING COUNT(CodPostal) > 2; A cláusula GROUP BY agrupa os clientes por código postal e a cláusula HAVING selecciona os grupos cujo número de elementos é superior a dois. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusulas GROUP BY e HAVING e Funções de Agregação (III) O seguinte comando lista, para cada código postal, o número de clientes que a ele estão associados (desde que exista mais do que um cliente): SELECT CodPostal, COUNT(CodPostal) FROM Cliente GROUP BY CodPostal HAVING COUNT(CodPostal) > 1; CodPostal = 1500 (Total:2) Cliente Nova tabela temporária CodPostal = 2100 (Total:2) Resultado Final CodPostal = 1300 (Total:1) Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusulas GROUP BY e HAVING e Funções de Agregação (IV) Sempre que existe uma função de agregação na cláusula SELECT, todos os restantes atributos da cláusula têm que estar incluídos na cláusula GROUP BY. O comando que de seguida se apresenta retorna o maior bilhete de identidade existente: SELECT MAX(Bi) FROM Cliente; Caso pretendêssemos visualizar o nome desse cliente, não poderíamos simplesmente acrescentar o atributo nome à cláusula SELECT. Pela regra anteriormente referida, teríamos que considerar a cláusula GROUP BY: SELECT MAX(Bi), NOME FROM Cliente GROUP BY Nome; No entanto, o resultado do comando seria a listagem de todos os nomes com a indicação do BI associado a cada nome. Mais adiante (Subquerys IV) apresenta-se a resolução desta interrogação. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Cláusulas GROUP BY e HAVING e Funções de Agregação (V) Para além das funções COUNT e MAX, existem outras, tais como SUM, AVG e MIN. Apenas a função COUNT não necessita de argumento: o primeiro comando retorna o total de registos de clientes enquanto o segundo devolve o total de clientes com o código postal conhecido: SELECT COUNT(*) FROM Cliente; SELECT COUNT(CodPostal) FROM Cliente; Note-se que o segundo comando é equivalente ao seguinte: SELECT COUNT(*) FROM Cliente WHERE CodPostal IS NOT NULL; Pedro Ramos, DCTI/ISCTE
SQL SELECT – Subquerys (I) Uma subquery é um comando SELECT dentro de um comando SELECT. Muitas interrogações apenas podem ser resolvidas através de subquerys. Um comando SELECT normalmente liga-se a outro através da cláusula WHERE. Os operadores IN e EXISTS são normalmente utilizadas nas subquerys. Operador IN devolve verdade quando um elemento pertence a um conjunto. Operador EXISTS devolve verdade caso a subquery retorne pelo menos uma linha. Pedro Ramos, DCTI/ISCTE
SQL SELECT – Subquerys (II) Os dois comandos abaixo apresentados (equivalentes) devolvem os nomes que estão associados a pelo menos duas pessoas (dois BI’s) (sem a cláusula DISTINCT o comando retornaria os nomes duplicados; os sinónimos das tabelas são necessários para evitar ambiguidades na condição WHERE da subquery): SELECT DISTINCT(Nome) FROM Cliente as Cliente1 WHERE NOME IN (SELECT NOME FROM Cliente as Cliente2 WHERE Cliente1.bi <> Cliente2.bi); SELECT DISTINCT(Nome) FROM Cliente as Cliente1 WHERE EXISTS (SELECT * FROM Cliente as Cliente2 WHERE Cliente1.bi <> Cliente2.bi AND Cliente1.Nome = Cliente2.Nome); Pedro Ramos, DCTI/ISCTE
SQL SELECT – Subquerys (III) Os operadores ALL (todos) e ANY (pelo menos um) também são frequentes nas subquerys. O comando para retornar o maior bilhete de identidade (e nome associado) existente é: SELECT Nome, BI FROM Cliente WHERE BI >= ALL (SELECT BI FROM Cliente); Caso pretendêssemos um bilhete de identidade que não fosse o menor, o comando seria: SELECT Nome, BI FROM Cliente WHERE BI > ANY (SELECT BI FROM Cliente); Pedro Ramos, DCTI/ISCTE
SQL SELECT – Subquerys (IV) As subquerys também podem ser colocadas nas cláusula SELECT e FROM. O seguinte exemplo devolve, para cada cliente, o total de facturas associadas: SELECT Nome, (SELECT COUNT(*) FROM Factura WHERE Factura.BI = Cliente.BI) FROM Cliente; O seguinte exemplo devolve, para cada cliente, o total de facturas associadas: SELECT DISTINCT Nome FROM (Select * From Cliente) as Cliente; Pedro Ramos, DCTI/ISCTE
SQL Comando UNION A união de comandos SELECT é efectuada através do operador UNION. O seguinte comando devolve os nomes dos clientes e fornecedores: SELECT Nome FROM Cliente UNION SELECT Nome FROM Fornecedor; Caso não pretendamos eliminar nomes duplicados o comando será: SELECT Nome FROM Cliente UNION ALL SELECT Nome FROM Fornecedor; Pedro Ramos, DCTI/ISCTE
SQL Comando UPDATE Um comando UPDATE para alteração de linhas obedece à seguinte estrutura: UPDATEtabela a alterar SETcoluna a alterar = expressão WHEREexpressão lógica que indica quais as linhas que pretendemos alterar O seguinte comando transforma os códigos postais 1200 em 1500: UPDATE Cliente SET CodPostal = 1500 WHERE CodPostal = 1200; Pedro Ramos, DCTI/ISCTE
SQL Comando DELETE Um comando DELETE para anulação de linhas obedece à seguinte estrutura: DELETE FROMtabela a anular WHEREexpressão lógica que indica quais as linhas que pretendemos alterar O seguinte comando apaga os códigos postais 1200 DELETE FROM Cliente WHERE CodPostal = 1200; Pedro Ramos, DCTI/ISCTE
SQL Comando INSERT Através do comando INSERT podem-se inserir uma linha ou várias linhas em simultâneo. Para inserir uma linha um comando INSERT obedece à seguinte estrutura: INSERT INTOtabela a inserir (colunas onde vão ser inseridos os valores) VALUES (valores a inserir) Para inserir um conjunto de linhas, um comando INSERT obedece à seguinte estrutura: INSERT INTOtabela a inserir (colunas onde vão ser inseridos os valores) SELECTvalores a inserir FROM... INSERT INTO Produto (cod_produto, tipo) VALUES (123456, ‘MP’); INSERT INTO Produto (cod_produto, tipo) SELECT cod_materia, ‘MP’ FROM Materia_Prima; Pedro Ramos, DCTI/ISCTE
SQL Optimizações de Querys (I) Na maioria dos SGBD’s a optimização de querys é feita automaticamente pelo planeador do SGBD. Ele, com base em estimativas de tempos e com base no histórico das transacções, decide qual a melhor estratégia a adoptar para executar uma query. Exemplos select PLAN('SELECT Titulo FROM Pub'); Scan pub sequentially select PLAN('SELECT ISBN FROM Pub'); Scan pub sequentially select PLAN('SELECT ISBN FROM Pub Order By ISBN'); Scan pub using index ndx_id select PLAN('SELECT * FROM Pub Where Data = 1900 ‘); Scan pub using index ndx_data select PLAN('SELECT * FROM Pub Where Data = 1900 or Data = 2000’); Scan pub sequentially Índice apenas em ISBN e Data Não vale a pena usar o índice Pedro Ramos, DCTI/ISCTE
SQL Optimizações de Querys (II) select PLAN('SELECT Nome, Localidade FROM Cliente KEY JOIN Localidade'); Scan Localidade sequentially Scan Cliente using foreign key FK_Localidade select PLAN('SELECT Nome, Localidade FROM Localidade KEY JOIN Cliente’); Scan Localidade sequentially Scan Cliente using foreign key FK_Localidade select PLAN( 'SELECT Nome FROM Cliente as CL1 Where NOT EXISTS ( SELECT * From Cliente as CL2 Where CL2.Nome = CL1.Nome AND Cl2.Bi<>Cl1.BI)'); Scan Cliente AS CL1 sequentially Scan Cliente AS CL2 sequentially select PLAN( 'SELECT Nome FROM Cliente as CL1 Where Cl1.NOME NOT IN ( SELECT CL2.Nome From Cliente as CL2 Where Cl2.Bi<>Cl1.BI)'); Scan Cliente AS CL1 sequentially Scan Cliente AS CL2 sequentially Diferentes comandos produzem o mesmo plano Pedro Ramos, DCTI/ISCTE
SQL Views As Views não são mais do que comandos SELECT armazenados. São por vezes denominadas tabelas temporárias. Note-se que o resultado de uma execução de uma view (os registos que ela devolve) depende dos registos armazenados no momento nas tabelas de suporte à view. As views podem ser utilizadas dentro de comandos SELECT. CREATE VIEW Clientes_Lisboa (BI, Nome) AS Select BI, Nome FROM Cliente KEY JOIN Localidade Where Localidade = 'Lisboa' WITH CHECK OPTION; Select Nome From Clientes_Lisboa; As views não podem conter a cláusula ORDER BY e apenas permitem a inserção, remoção e alteração de registos caso não contenham as cláusulas GROUP BY e UNION. A cláusula CHECK OPTION rejeita alterações e inserções na view que não obedeçam ao critério da cláusula SELECT que a define. Pedro Ramos, DCTI/ISCTE
SQL Prepare Statement O comando Prepare Statement permite optimizar acessos à base de dados que são efectuados múltiplas vezes em uma transacção. Quando um comando SQL é enviado ao SGBD, este, para além de ter o interpretar (parsing), tem de gerar um plano para a sua realização. O comando Prepare Statement evita que essas duas tarefas sejam executadas mais do que uma vez. A comando apenas se justifica quando o SQL é utilizado dentro de outra linguagem de programação (Java, C, Visual Basic, etc.) ou em Stored Procedures (ver mais adiante). Exemplo (simplificado, mais adiante apresenta-se um exemplo completo em JAVA) PREPARE calc_factura("Update Factura Set Valor = ? Where Num_Factura = ? ;"); calc_factura.setDouble(1, totalFactura); calc_factura.setInt(2, lastFactura); calc_factura.executeSQL() Passagem de parâmetros Execução Pedro Ramos, DCTI/ISCTE
SQL Stored Procedures Os Stored Procedures (SP) são procedimentos SQL compilados e armazenados junto da base de dados. Trata-se da forma mais eficiente de executar comandos SQL. Para além dos comandos SQL é possível utilizar as habituais primitivas de controlo (If, While), os habituais operadores lógicos e variáveis. Trata-se no entanto de uma linguagem simples que não substitui as linguagens procedimentais (C, Java, etc.). É possível passar parâmetros para um SP, assim como um SP retornar valores (nomeadamente o resultado de comandos SELECT). Os SP podem ser chamados dentro de um comando SELECT ou a partir de uma linguagem procedimental (através da primitiva CALL). Pedro Ramos, DCTI/ISCTE
SQL Stored Procedures - Exemplos create procedure dba.newPubdelay() begin declare i integer; declare lastISBN integer; select max(ISBN) into lastISBN from Pub; set i=1; while i < 100000 loop set i=i+1 end loop; insert into pub(isbn) values(lastISBN+1); commit work end Se após este SP for executado um outro idêntico sem o ciclo (simula uma pausa) ocorre uma situação de dead lock. create procedure dba.getPubAno(in Par_Ano integer) result(ISBN integer,Titulo long varchar) begin select ISBN,Titulo from Pub where DAta = Par_Ano end O comando CALL getPubAno(2000); retorna as publicações de 2000 Pedro Ramos, DCTI/ISCTE