Baixe o app para aproveitar ainda mais
Prévia do material em texto
1 Esquemas de Bancos de Dados .......................................................................................................................... 2 Álgebra Relacional ............................................................................................................................................. 4 Operações Fundamentais ................................................................................................................................ 4 Seleção ....................................................................................................................................................... 4 Projeção ...................................................................................................................................................... 5 Produto Cartesiano ..................................................................................................................................... 5 Renomeação ............................................................................................................................................... 6 União .......................................................................................................................................................... 7 Diferença .................................................................................................................................................... 8 Operações Adicionais ................................................................................................................................... 12 Interseção.................................................................................................................................................. 12 Junção Natural .......................................................................................................................................... 13 Divisão...................................................................................................................................................... 14 Cálculo Relacional ............................................................................................................................................ 16 Cálculo Relacional de Tuplas ....................................................................................................................... 16 Definições Formais ................................................................................................................................... 16 Exemplos .................................................................................................................................................. 16 Cálculo Relacional de Domínios .................................................................................................................. 17 Definições Formais ................................................................................................................................... 17 Exemplos .................................................................................................................................................. 17 QBE .............................................................................................................................................................. 19 SQL .................................................................................................................................................................. 21 Declaração de Domínios ............................................................................................................................... 22 Manipulação de Tabelas ............................................................................................................................... 22 DML ............................................................................................................................................................. 22 DQL .............................................................................................................................................................. 23 Segunda Lista de Exemplos .......................................................................................................................... 25 Terceira Lista de Exemplos .......................................................................................................................... 25 SQL Embutida .............................................................................................................................................. 28 Reconhecendo Comandos SQL Embutidos .............................................................................................. 28 Uma Primeira Visão da SQL Embutida .................................................................................................... 28 Variáveis da Linguagem Hospedeira na SQL Embutida........................................................................... 28 Declaração de Variáveis ........................................................................................................................... 29 SELECT na SQL Embutida ...................................................................................................................... 29 UPDATE em SQL Embutida .................................................................................................................... 29 DELETE e INSERT na SQL Embutida .................................................................................................... 29 Outros Comandos SQL Embutidos ........................................................................................................... 30 Cursores .................................................................................................................................................... 30 O Uso de Cursores Para UPDATE e DELETE ........................................................................................ 30 2 Esquemas de Bancos de Dados Um esquema de relação é uma lista de atributos e seus domínios correspondentes. Um esquema de banco de dados é o projeto lógico do BD enquanto uma instância de banco de dados é o conjunto de dados no BD em um determinada instante. Exemplo: Considere-se um modelo bancário com cinco relações depósitos, empréstimos, correntistas, filiais e clientes. Os esquemas correspondentes poderiam ser: Depósitos Depósito_esquema(nome_f,conta_#,nome_c,saldo) ou Depósito_esquema(nome_f:string,conta_#:inteiro,nome_c:string,saldo:inteiro) Filiais Filial_esquema(nome_f,ativo,cidade_f) Correntistas Correntista_esquema(nome_c,rua,cidade_c) Empréstimos Empréstimos_esquema(nome_f,empréstimo_#,nome_c,valor) Clientes Cliente_esquema(nome_c,gerente) depósitos nome_f conta_# nome_c saldo Bingen 22473 Lindalva 889 Botafogo 20018 Pedro 8450 Flamengo 20210 Pedro 5100 Flamengo 20500 Paulo 2315 Icaraí 19872 João 3243 Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 empréstimos nome_f empréstimo-# nome_c valor Bingen 6698 Lindalva 1500 Flamengo 5578 Paulo 2000 Icaraí 1455 João 1000 Madureira 3367 Pedro 2000 filiais nome_f ativo cidade_f Icaraí 9000000 Niterói Bingen 17000000 Petrópolis Botafogo 23000000 Rio de Janeiro Flamengo 34000000 Rio de Janeiro Madureira 21000000 Rio de Janeiro 3 correntistas nome_c rua cidade_c João Miguel de Frias Niterói Laerte Gavião Peixoto Niterói Lindalva Alfenas Petrópolis Geraldo Curimatá Rio de Janeiro Laura Cotingo Rio de Janeiro Paulo Mem de Sá Rio de Janeiro Pedro Curimatá Rio de Janeiro Rosa Uruguai Rio de Janeiro clientes nome_c gerente João Erasmo Laerte Pedro Laura João Lindalva João Paulo Célia Pedro Pedro 4 Álgebra Relacional A Álgebra Relacional é uma linguagem de consulta procedimental que possui seis operaçõesfundamentais e diversas outras. Cada uma das operações da Álgebra Relacional que se seguem produz como resultado uma relação. Operações fundamentais * Seleção (unária) * Projeção (unária) * Renomeação (unária) * Produto cartesiano (binária) * União (binária) * Diferença (binária) Outras operações * Interseção * Junção natural * Divisão * Atribuição Operações Fundamentais Seleção Esta operação seleciona as tuplas que atendem a uma determinada condição. É denotada pela letra grega sigma com o predicado aparecendo como subscrito. A relação argumento aparece entre parênteses depois do sigma. Para selecionar as tuplas da relação empréstimos aonde a filial seja “Madureira”, escreve-se nome f Madureira empré stimos_ " "( ) A relação resultado será constituída de apenas uma tupla Madureira 3367 Pedro 2000 Para obter os empréstimos superiores a 1200 escreve-se nome f Madureira valor empré stimos_ " " ( ) 1200 Para obter os clientes que tenham o mesmo nome que seus gerentes pode-se escrever nome c gerente clientes_ ( ) A relação resultado será constituída de apenas uma tupla nome_c gerente Pedro Pedro 5 Projeção Esta operação copia de sua relação argumento apenas os atributos especificados. Como uma relação é um conjunto eventuais tuplas duplicadas são eliminadas. Projeção é denotada pela letra grega pi maiúsculo com os atributos aparecendo como subscritos. Para obter uma relação de empréstimos mostrando apenas os correntistas e filiais escreve-se empré stimos nome f nome c_ , _ obtendo-se nome_f nome_c Bingen Lindalva Flamengo Paulo Icaraí João Madureira Rosa Madureira Pedro Para obter os nomes dos correntistas que tenham o mesmo nome que seus gerentes escreve-se ( ( )) _ _nome c nome c gerente clientes obtendo-se nome_c Pedro Produto Cartesiano O Produto Cartesiano de duas relações é denotado por . O resultado da operação r1 r2 é uma nova relação com uma tupla para cada possível par de tuplas de r1 e r2. Para evitar ambigüidade os atributos tem seus nomes concatenados com os nomes das relações a que pertencem. Quando inexiste ambigüidade o nome da relação pode ser omitido. O resultado da operação é uma nova relação. Se r1 possui n1 tuplas e r2 possui n2 tuplas então r = r1 r2 possui n1.n2 tuplas. Para encontrar os clientes do gerente “João” e a cidade na qual eles vivem necessita-se de informações das relações correntistas e clientes e pode-se escrever clientes nome c correntistas nome c gerente João clientes correntisitas. _ . _ " " obtendo-se nome_c gerente nome_c rua cidade_c Laura João Laura Cotingo Rio de Janeiro Lindalva João Lindalva Alfenas Petrópolis Se desta relação apenas se desejasse o nome do correntista e sua cidade usar-se-ia uma projeção ( ). _ . _ . _ " "clientes nome c clientes nome c correntistas nome c gerente João clientes correntisitas obtendo-se nome_c cidade_f 6 Laura Rio de Janeiro Lindalva Petrópolis Renomeação A operação de renomeação resolve os problemas que ocorrem quando se faz o produto cartesiano de uma relação por ela mesma. Considere-se, por exemplo, que se deseja encontrar os nomes dos correntistas que moram na mesma cidade e na mesma rua que Pedro. Pode-se obter a cidade e a rua de Pedro escrevendo ( ( )) , _ _ " "rua cidade c nome c Pedro correntistas obtendo-se rua cidade_c Curimatá Rio de Janeiro Para obter outros correntistas com a mesma informação necessita-se referenciar novamente a relação correntistas, da forma P rua cidade c nome c Pedrocorrentistas correntistas( ( ( ( )))), _ _ " " Na expressão anterior P é um predicado de seleção requerendo a igualdade de rua e cidade_c. Para distinguir entre os diferentes valores de rua aparecendo no produto cartesiano usa-se o operador de renomeação denotado pela letra grega ro cujo índice é o novo nome da relação e o argumento entre parênteses é o nome anterior, ou seja corrent rua correntistas rua corrent cidade c correntistas cidade c rua cidade c nome c Pedro corrent correntistas correntistas 2 2 2 . . . _ . _ , _ _ " " ( ( ( ( ( ))))) obtendo-se correntistas corrent2 nome_c rua cidade_c nome_c rua cidade_c Pedro Curimatá Rio de Janeiro Pedro Curimatá Rio de Janeiro Pedro Curimatá Rio de Janeiro Geraldo Curimatá Rio de Janeiro Geraldo Curimatá Rio de Janeiro Pedro Curimatá Rio de Janeiro Geraldo Curimatá Rio de Janeiro Geraldo Curimatá Rio de Janeiro Como o que se quer dessa relação é apenas o nome dos correntistas faz-se uma projeção ( ( ( ( ( ( )))))) . _ . . . _ . _ , _ _ " " correntistas nome c corrent rua correntistas rua corrent cidade c correntistas cidade c rua cidade c nome c Pedro corrent correntistas correntistas 2 2 2 obtendo-se nome_c Pedro Geraldo 7 União A operação de união para funcionar tal como na teoria dos conjuntos necessita que as relações a se unir tenham o mesmo número de atributos e que os domínios dos atributos correspondentes coincidam. Para encontrar os usuários da agência Madureira é preciso encontrar todos aqueles que ou tenham conta na agência ou que tenham feito empréstimos lá, escrevendo-se nome f Madureiranome c nome f Madureiranome cempré stimos depósitos_ " "_ _ " "_ Como em todas as operações de conjuntos as duplicadas são eliminadas e o que se obtém é empréstimos em Madureira nome_f empréstimo_# nome_c valor Madureira 3367 Pedro 2000 empréstimos em Madureira nome_c Pedro depósitos em Madureira nome_f conta_# nome_c saldo Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 depósitos em Madureira nome_c Rosa Pedro usuários em Madureira nome_c Rosa Pedro 8 Diferença A operação diferença encontra as tuplas que estão em uma relação mas não estão na outra. Para encontrar os usuários do banco que na agência Madureira tenham conta corrente mas não tenham empréstimos pode-se escrever nome f Madureiranome c nome f Madureiranome cdepósitos empré stimos_ " "_ _ " "_ o resultado obtido é depósitos nome_f conta_# nome_c saldo Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 depósitos em Madureira nome_c Rosa Pedro empréstimos nome_f empréstimo_# nome_c valor Madureira 3367 Pedro 2000 empréstimos em Madureira nome_c Pedro usuários com conta e sem empréstimos em Madureira nome_c Rosa 9 Para encontrar o maior saldo dentre as contas correntes do banco o que se faz é encontrar uma relação r que não contenha o maior saldo e verificar a diferença entre a relação anterior e a relação de depósitos. Para encontrar r o que se faz é depósitos saldo d saldo ddepósitos saldo depósitos depósitos. .. obtendo-se depósitos d(depósitos) depósitos d nome_f conta_# nome_c saldo nome_f conta_# nome_c saldo Bingen 22473 Lindalva 889 Bingen 22473 Lindalva 889 Bingen 22473 Lindalva 889 Botafogo 20018 Pedro 8450 Bingen 22473 Lindalva 889 Flamengo 20210 Pedro 5100 Bingen 22473 Lindalva 889 Flamengo 20500 Paulo 2315 Bingen 22473 Lindalva 889 Icaraí 19872 João 3243 Bingen 22473 Lindalva 889 Madureira 19880 Rosa 5312 Bingen 22473 Lindalva 889 Madureira 19890 Pedro 4111 Botafogo 20018 Pedro 8450 Bingen 22473 Lindalva 889 Botafogo 20018 Pedro 8450 Botafogo 20018 Pedro 8450 Botafogo 20018 Pedro 8450 Flamengo 20210 Pedro 5100 Botafogo 20018 Pedro 8450 Flamengo 20500 Paulo 2315 Botafogo 20018 Pedro 8450 Icaraí 19872 João 3243 Botafogo 20018 Pedro 8450 Madureira 19880 Rosa 5312 Botafogo 20018 Pedro 8450 Madureira 19890 Pedro 4111 Flamengo 20210 Pedro 5100 Bingen 22473 Lindalva 889 Flamengo 20210 Pedro 5100 Botafogo 20018 Pedro 8450 Flamengo 20210 Pedro5100 Flamengo 20210 Pedro 5100 Flamengo 20210 Pedro 5100 Flamengo 20500 Paulo 2315 Flamengo 20210 Pedro 5100 Icaraí 19872 João 3243 Flamengo 20210 Pedro 5100 Madureira 19880 Rosa 5312 Flamengo 20210 Pedro 5100 Madureira 19890 Pedro 4111 Flamengo 20500 Paulo 2315 Bingen 22473 Lindalva 889 Flamengo 20500 Paulo 2315 Botafogo 20018 Pedro 8450 Flamengo 20500 Paulo 2315 Flamengo 20210 Pedro 5100 Flamengo 20500 Paulo 2315 Flamengo 20500 Paulo 2315 Flamengo 20500 Paulo 2315 Icaraí 19872 João 3243 Flamengo 20500 Paulo 2315 Madureira 19880 Rosa 5312 Flamengo 20500 Paulo 2315 Madureira 19890 Pedro 4111 Icaraí 19872 João 3243 Bingen 22473 Lindalva 889 Icaraí 19872 João 3243 Botafogo 20018 Pedro 8450 Icaraí 19872 João 3243 Flamengo 20210 Pedro 5100 Icaraí 19872 João 3243 Flamengo 20500 Paulo 2315 Icaraí 19872 João 3243 Icaraí 19872 João 3243 Icaraí 19872 João 3243 Madureira 19880 Rosa 5312 Icaraí 19872 João 3243 Madureira 19890 Pedro 4111 10 continuação de depósitos d(depósitos) depósitos d nome_f conta_# nome_c saldo nome_f conta_# nome_c saldo Madureira 19880 Rosa 5312 Bingen 22473 Lindalva 889 Madureira 19880 Rosa 5312 Botafogo 20018 Pedro 8450 Madureira 19880 Rosa 5312 Flamengo 20210 Pedro 5100 Madureira 19880 Rosa 5312 Flamengo 20500 Paulo 2315 Madureira 19880 Rosa 5312 Icaraí 19872 João 3243 Madureira 19880 Rosa 5312 Madureira 19880 Rosa 5312 Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 Madureira 19890 Pedro 4111 Bingen 22473 Lindalva 889 Madureira 19890 Pedro 4111 Botafogo 20018 Pedro 8450 Madureira 19890 Pedro 4111 Flamengo 20210 Pedro 5100 Madureira 19890 Pedro 4111 Flamengo 20500 Paulo 2315 Madureira 19890 Pedro 4111 Icaraí 19872 João 3243 Madureira 19890 Pedro 4111 Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 Madureira 19890 Pedro 4111 depósitos.saldo < d.saldo em depósitos d(depósitos) depósitos d nome_f conta_# nome_c saldo nome_f conta_# nome_c saldo Bingen 22473 Lindalva 889 Botafogo 20018 Pedro 8450 Bingen 22473 Lindalva 889 Flamengo 20210 Pedro 5100 Bingen 22473 Lindalva 889 Flamengo 20500 Paulo 2315 Bingen 22473 Lindalva 889 Icaraí 19872 João 3243 Bingen 22473 Lindalva 889 Madureira 19880 Rosa 5312 Bingen 22473 Lindalva 889 Madureira 19890 Pedro 4111 Flamengo 20210 Pedro 5100 Botafogo 20018 Pedro 8450 Flamengo 20500 Paulo 2315 Botafogo 20018 Pedro 8450 Flamengo 20500 Paulo 2315 Flamengo 20210 Pedro 5100 Flamengo 20500 Paulo 2315 Icaraí 19872 João 3243 Flamengo 20500 Paulo 2315 Madureira 19880 Rosa 5312 Flamengo 20500 Paulo 2315 Madureira 19890 Pedro 4111 Icaraí 19872 João 3243 Botafogo 20018 Pedro 8450 Icaraí 19872 João 3243 Flamengo 20210 Pedro 5100 Icaraí 19872 João 3243 Madureira 19880 Rosa 5312 Icaraí 19872 João 3243 Madureira 19890 Pedro 4111 Madureira 19880 Rosa 5312 Botafogo 20018 Pedro 8450 Madureira 19890 Pedro 4111 Flamengo 20210 Pedro 5100 Madureira 19890 Pedro 4111 Madureira 19880 Rosa 5312 depósitos saldo 889 5100 2315 3243 5312 4111 11 Essa relação contém todos os saldos exceto o maior deles. Para finalizar a consulta calcula-se a diferença depósitos depósitos depósitos depósitos saldo depósitos saldo d saldo ddepósitos saldo. . .. O resultado é depósitos saldo 8450 12 Operações Adicionais Interseção A operação de interseção retorna uma relação que contém as tuplas que estejam em ambas as relações argumentos da interseção. r s = r - (r - s) Para obter todos os usuários que possuam tanto empréstimos quanto contas correntes no banco escreve-se nome f Madureiranome c nome f Madureiranome cempré stimos depósitos_ " "_ _ " "_ obtendo-se empréstimos em Madureira nome_f empréstimo_# nome_c valor Madureira 3367 Pedro 2000 empréstimos em Madureira nome_c Pedro depósitos em Madureira nome_f conta_# nome_c saldo Madureira 19880 Rosa 5312 Madureira 19890 Pedro 4111 depósitos em Madureira nome_c Rosa Pedro usuários com empréstimos e depósitos em Madureira nome_c Rosa Pedro 13 Junção Natural A operação de junção natural combina o produto cartesiano e a seleção em uma só operação. A seleção força a igualdade nos atributos que aparecem nos esquemas das duas relações. Para encontrar os usuários que possuem empréstimos no banco e as cidades em que moram é necessário utilizar as relações empréstimos e correntistas, de uma das formas abaixo empré stimos nome c correntistas nome cempré stimos nome c cidade c empré stimos correntistas. _ . _. _ , _ empré stimos correntistas empré stimos nome c cidade c . _ , _ O resultado é empréstimos correntistas empréstimos correntistas nome_f empréstimo_# nome_c valor nome_c rua cidade_c Bingen 6698 Lindalva 1500 João Miguel de Frias Niterói Bingen 6698 Lindalva 1500 Laerte Gavião Peixoto Niterói Bingen 6698 Lindalva 1500 Lindalva Alfenas Petrópolis Bingen 6698 Lindalva 1500 Geraldo Curimatá Rio de Janeiro Bingen 6698 Lindalva 1500 Laura Cotingo Rio de Janeiro Bingen 6698 Lindalva 1500 Paulo Mem de Sá Rio de Janeiro Bingen 6698 Lindalva 1500 Pedro Curimatá Rio de Janeiro Bingen 6698 Lindalva 1500 Rosa Uruguai Rio de Janeiro Flamengo 5578 Paulo 2000 João Miguel de Frias Niterói Flamengo 5578 Paulo 2000 Laerte Gavião Peixoto Niterói Flamengo 5578 Paulo 2000 Lindalva Alfenas Petrópolis Flamengo 5578 Paulo 2000 Geraldo Curimatá Rio de Janeiro Flamengo 5578 Paulo 2000 Laura Cotingo Rio de Janeiro Flamengo 5578 Paulo 2000 Paulo Mem de Sá Rio de Janeiro Flamengo 5578 Paulo 2000 Pedro Curimatá Rio de Janeiro Flamengo 5578 Paulo 2000 Rosa Uruguai Rio de Janeiro Icaraí 1455 João 1000 João Miguel de Frias Niterói Icaraí 1455 João 1000 Laerte Gavião Peixoto Niterói Icaraí 1455 João 1000 Lindalva Alfenas Petrópolis Icaraí 1455 João 1000 Geraldo Curimatá Rio de Janeiro Icaraí 1455 João 1000 Laura Cotingo Rio de Janeiro Icaraí 1455 João 1000 Paulo Mem de Sá Rio de Janeiro Icaraí 1455 João 1000 Pedro Curimatá Rio de Janeiro Icaraí 1455 João 1000 Rosa Uruguai Rio de Janeiro Madureira 3367 Pedro 2000 João Miguel de Frias Niterói Madureira 3367 Pedro 2000 Laerte Gavião Peixoto Niterói Madureira 3367 Pedro 2000 Lindalva Alfenas Petrópolis Madureira 3367 Pedro 2000 Geraldo Curimatá Rio de Janeiro Madureira 3367 Pedro 2000 Laura Cotingo Rio de Janeiro Madureira 3367 Pedro 2000 Paulo Mem de Sá Rio de Janeiro Madureira 3367 Pedro 2000 Pedro Curimatá Rio de Janeiro Madureira 3367 Pedro 2000 Rosa Uruguai Rio de Janeiro 14 empréstimo.nome = correntistas.nome em empréstimos correntistas empréstimos correntistas nome_f empréstimo_# nome_c valor nome_c rua cidade_c Bingen 6698 Lindalva 1500 Lindalva Alfenas Petrópolis Flamengo 5578 Paulo 2000 Paulo Mem de Sá Rio de Janeiro Icaraí 1455 João 1000 João Miguel de Frias Niterói Madureira 3367 Pedro 2000 Pedro Curimatá Rio de Janeiro nome_c cidade_c Lindalva Petrópolis Paulo Rio de Janeiro João Niterói Pedro Rio de Janeiro Divisão A operação de divisão destina-se às consultas que incluem a frase “para todo”. Quando se divide uma relação de grau m+n (com m+n colunas) por uma relação grau n (com n colunas) se obtém uma relação grau m (com m colunas). Para encontrar todos os usuários que possuem contas em todas as agências situadas no Rio de Janeiro usam-se três passos. No primeiro determinam-se os nomes das agências do Rio de Janeiro r filiaiscidade f RiodeJaneironome f1 _ " "_ obtendo-se filiais nome_f ativo cidade_f Botafogo 23000000 Rio de Janeiro Flamengo 34000000 Rio de Janeiro Madureira 21000000 Rio de Janeiro nome_f Botafogo Flamengo Madureira 15 O passo seguinte consiste em determinar os pares nome_c e nome_f para os quais o correntista possua uma conta r depósitos nome c nomef2 _ , _ obtendo-se depósitos nome_f nome_c Botafogo Pedro Flamengo Pedro Flamengo Paulo Madureira Rosa Madureira Pedro No terceiro passo é preciso determinar os correntistas que aparecem em r2 com todos os nomes de filiais de r1, o que é feito pela operação de divisão r2 r1. depósitos filiaisnome c nome f cidade f RiodeJaneironome f_ , _ _ " "_ obtendo-se nome_c Pedro 16 Cálculo Relacional Cálculo Relacional de Tuplas Definições Formais A notação t r(Q(t)) significa “existe uma tupla t na relação r tal que o predicado Q(t) é verdadeiro”. Uma expressão de tupla de Cálculo Relacional é da forma {t P(t)} onde P é uma fórmula. Uma variável de tupla é uma variável livre a menos que seja quantificada por ou . Quando isto ocorrer a variável é dita ligada. Uma fórmula é constituída de átomos. Um átomo é de uma das formas: s r, aonde s é uma variável de tupla e r é uma relação, não se aceitando para a relação ; s[x] u[y], aonde s e u são variáveis de tupla, x e y são atributos e é um operador de comparação s[x] c, aonde c é uma constante no domínio do atributo x As fórmulas são constituídas de átomos de acordo com as seguintes regras: Um átomo é uma fórmula Se P é uma fórmula, então P e (P) são fórmulas Se P1 e P2 são fórmulas, então P1 P2, P1 P2 e P1=P2 também são fórmulas Se P(s) é uma fórmula contendo uma variável livre de tupla, s, então s r(P(s)) e s r(P(s)) também são fórmulas São equivalentes conhecidos P1 P2 = (P1 P2) t r(P(t)) = t r(P(t)) P1 P2 = P1 P2 Exemplos Para encontrar todos os atributos das tuplas correspondentes aos empréstimos maiores do que 1200 escreve-se {t t empréstimos t[valor] > 1200} Para encontrar apenas os nomes dos correntistas correspondentes aos empréstimos maiores do que 1200 procura-se o conjunto de todas as tuplas t tais que existe uma tupla s na relação empréstimos para a qual os valores de t e de s para os atributos nome_c são iguais e o valor de s para o atributo valor é maior do que 1200 e escreve-se {t s empréstimos (t[nome_c] = s[nome_c] s[valor] > 1200)} Com outra notação também pode-se escrever, para a mesma consulta {t[nome_c] t empréstimos t[valor] > 1200)} Para encontrar os usuários que obtiveram empréstimos na agência Madureira obtendo também as cidades em que moram o que se tem de recuperar é o conjunto das tuplas (nome_c,cidade_c) para as quais nome_c é um tomador de empréstimo na agência Madureira e cidade é a cidade aonde mora nome_c. A variável s servirá para caracterizar o usuário como tomador de empréstimo na agência Madureira. A variável u é restrita a pertencer ao mesmo usuário s e garante que cidade_c é a moradia do usuário. {t s empréstimos (t[nome_c] = s{nome_c] s[nome_f] = “Madureira”) u correntistas (u[nome_c] = s[nome_c] t[cidade_c] = u[cidade_c])} 17 Para encontrar os usuários que possuem uma conta, um empréstimo, ou ambos, na agência Madureira {t s empréstimos (t[nome_c] = s{nome_c] s[nome_f] = “Madureira”) u depósitos (u[nome_c] = s[nome_c] u[nome_f] = “Madureira”)} Para encontrar os usuários que possuem tanto uma conta quanto um empréstimo na agência Madureira basta trocar, na expressão anterior, por . Para encontrar os usuários que possuem uma conta na agência Madureira mas não possuem um empréstimo lá {t u depósitos (t[nome_c] = u{nome_c] s[nome_f] = “Madureira”) s empréstimos (t[nome_c] = s[nome_c] s[nome_f] = “Madureira”)} Para encontrar todos os usuários que possuem uma conta em todas as agências da cidade do Rio de Janeiro, na Álgebra Relacional usa-se divisão e no Cálculo Relacional de tuplas usa-se a implicação. O resultado é o conjunto de todas as tuplas nome_c t tais que para todas as tuplas u na relação filiais, se os valores de u para o atributo cidade forem iguais a Rio de Janeiro, então o usuário tem uma conta na filial cujo nome aparece no atributo nome_f de u. {t u filias (u[cidade_f] = “Rio de Janeiro”) s depósitos (t[nome_c] = s[nome_c] u[nome_f] = s[nome_f])} Uma expressão {t P(t)} é segura se for finita e se todos os valores que aparecem no resultado forem valores do domínio de P. Como exemplo de expressão infinita pode-se escrever {t (t empréstimos)} Cálculo Relacional de Domínios Definições Formais Uma expressão é da forma {<x1, x2, ..., xn> P(x1, x2, ..., xn)} , aonde xi1 , 1 i n representam variáveis de domínios e P é uma fórmula. Um átomo no Cálculo Relacional de domínio é de uma das formas: <x1, x2, ..., xn> r, aonde r é uma relação de n atributos e xi1 , 1 i n são variáveis de domínio ou constantes ; x [y, aonde, x e y são variáveis de domínio e é um operador de comparação x c, aonde c é uma constante no domínio do atributo x As fórmulas são constituídas de átomos de acordo com as seguintes regras: Um átomo é uma fórmula Se P é uma fórmula, então P e (P) são fórmulas Se P1 e P2 são fórmulas, então P1 P2, P1 P2 e P1=P2 também são fórmulas Se P(x) é uma fórmula aonde x é uma variável de domínio, então x (P(x)) e x (P(x)) também são fórmulas Exemplos Para encontrar todos os atributos das tuplas correspondentes aos empréstimos maiores do que 1200 escreve-se {<f1 e1 c1 v> <f1 e1 c1 v> empréstimos v > 1200} símbolos para os atributos de empréstimos nome_f empréstimo-# nome_c valor 18 Para encontrar apenas os nomes dos correntistas correspondentes aos empréstimos maiores do que 1200 escreve-se {<c> f1 e1 v (<f1 e1 c1 v> empréstimos v > 1200)} Para encontrar os usuários que obtiveram empréstimos na agência Madureira obtendo também as cidades em que moram escreve-se {<c1 x> f1 e1 v (<f1 e1 c1 v> empréstimos f = “Madureira”) y(<c1 y1 x> correntistas)} símbolos para os atributos de correntistas nome_c rua cidade_c Para encontrar os usuários que possuem uma conta, um empréstimo, ou ambos, na agência Madureira escreve-se {<c> f1 e1 v (<f1 e1 c1 v> empréstimos f = “Madureira”) f1 o1 n(<f1 o1 c1 s> depósitos f = “Madureira”)} símbolos para os atributos de depósitos nome_f conta_# nome_c saldo Para encontrar todos os usuários que possuem uma conta em todas as agências da cidade do Rio de Janeiro escreve-se {<c> x1 y1 z ((<x1 y1 z > filiais) z “Rio de Janeiro” ( o1 s(<x1 o1 c1 s> depósitos ))} Se esta expressão for considerada de difícil entendimento ela pode ser re escrita utilizando implicação. {<c> nf1 at1 cf ((<nf1 at1 cf > filiais) cf = “Rio de Janeiro”) o1 s(<nf1 o1 c1 s> depósitos ))} símbolos para os atributos de filiais nome_f ativo cidade_f símbolos para os atributos de depósitos nome_f conta_# nome_c saldo São equivalentes: • A Álgebra Relacional • O Cálculo Relacional de tuplas restrito a expressões seguras • O Cálculo Relacional de domínios restrito a expressões seguras A diferença entre cálculo relacional de tuplas e cálculo relacional de domínios está na visão do usuário sobre os dados. No cálculo de tuplas o usuário tem de reciocinar sob a forma de tuplas das relações existentes. No cálculo de domínios o usuário escolhe as entidades que quiser, inclusive atributos de relações existentes. Uma consulta no cálculo de domínios é mais simples do que no cálculo de tuplas quando ocorrerem procutos cartesianos de uma relação por si mesma (isto é, quando uma variável de domínio ocorrer mais de uma vez na consulta). 19 QBE A linguagem “Query By Example”, ou QBE, é uma linguagem de consulta baseada no cálculo relacional de domínios. A linguagem possui uma sintaxe bidimensional pois o sistema exibe na tela do terminal um “esqueleto” de tabela em branco.As consultas são feitas por marcação, no “esqueleto”, dos atributos que se deseja obter. Para identificar o que se deseja identificam-se as transações previstas pela linguagem por uma inicial maiúscula seguida de um ponto, da forma “P.” para impressão, “I.” para inclusão, “U.” para modificação e “D.” para exclusão. Quando esses indicadores de transações aparecerem à esquerda de uma tupla no “esqueleto” referem-se a toda a tupla. Quando aparecerem dentro de uma coluna referem-se apenas ao atributo correspondente. Para formular uma consulta insere-se nas colunas do “esqueleto” as cláusulas de condição desejadas e indica-se o que se deseja ver inserindo-se “P.” nas colunas dos atributos desejados. A resposta da consulta é fornecida pelo sistema preenchendo as colunas do próprio “esqueleto” no qual foi formulada a consulta. Para utilizar a linguagem QBE nas relações existentes ao se disparar o programa o sistema exibe os “esqueletos” das tabelas da forma depósitos nome_f conta_# nome_c saldo empréstimos nome_f empréstimo-# nome_c valor filiais nome_f ativo cidade_f correntistas nome_c rua cidade_c clientes nome_c gerente Para listar os nomes das filiais do banco escreve-se filiais nome_f ativo cidade_f P. Para listar os nomes das filiais do banco na cidade do Rio de Janeiro escreve-se filiais nome_f ativo cidade_f P. Rio de Janeiro 20 Para listar os nomes das filiais do banco com ativo superior a 2.000.000 escreve-se filiais nome_f ativo cidade_f P. > 2000000 Para listar os nomes e as cidades dos correntistas que possuam saldo superior a 2.000 escreve-se correntistas nome_c rua cidade_c P.X P depósitos nome_f conta_# nome_c saldo X > 2000 Para listar os nomes dos clientes que tenham conta na agência Icaraí ou que tenham empréstimos superiores a 3.000 escreve-se empréstimos nome_f empréstimo-# nome_c valor Icaraí P.X P.Y > 3000 Para listar todos os atributos dos clientes que tenham empréstimos na agência Flamengo escreve-se empréstimos nome_f empréstimo-# nome_c valor P. Flamengo 21 SQL A linguagem “Structured Query Language”, ou SQL, é baseada no modelo relacional mas não é uma rígida implementação daquele método. A primeira versão da linguagem foi padronizada em 1986. Uma revisão feita em 1992 foi chamada de SQL2. Presentemente trabalha-se em nova versão prevista para meados de 1998 chamada de SQL3. SQL3 pretende ser uma linguagem computacional completa para a definição e gerenciamento de objetos complexos persistentes. As unidades básicas da linguagem são tabelas, linhas e colunas. Uma relação é mapeada em uma tabela, uma coluna representa um elemento de dado presente na tabela e uma linha representa uma instância de um registro. Algumas de suas características (da SQL) são: • A linguagem não é sensível a espaços CR, LF, TAB etc. • Palavras reservadas são limitadas por vírgulas quando aplicável e usam-se parênteses para agrupamentos. • Quando se utiliza múltiplas consultas usa-se “;” para separar umas das outras. • As consultas são indiferentes a maiúsculas. Um esquema é uma coleção de zero ou mais tabelas sendo que cada tabela só pode pertencer a um esquema. Um catálogo contém zero ou mais esquemas. A linguagem SQL é dividida em três partes: • “Data Definition Language”, ou DDL, para definição dos dados, criação de tabelas (CREATE TABLE). • “Data Control Language”, ou DCL, para controlar a segurança e o acesso aos dados (GRANT REVOKE). • “Data Manipulation Language”, ou DML, para manipulação dos dados, armazenamento, modificação e recuperação. A linguagem SQL pode ser utilizada pelos usuários finais. As tabelas relacionais são autônomas. Referências cruzadas entre tabelas podem ser estabelecidas por comandos SQL. A álgebra relacional opera sobre conjuntos. Para bancos de dados relacionais não é preciso navegar sobre arquivos. Toda consulta retorna todos os dados que respondem a consulta. Usuários da linguagem SQL não precisam se preocupar com índices, chaves ou qualquer outra estrutura de navegação. Para esses usuários qualquer campo pode ser uma chave. Quando duas ou mais tabelas são relacionadas pela linguagem SQL existe uma junção. Os BD relacionais tentam postergar o mapeamento de relações entre as estruturas de dados até o momento em que um agente deseja que algo seja feito. Muito embora a linguagem SQL não seja extremamente amigável sua operação é intuitiva para muitos usuários e mais simples que a maioria das linguagens procedimentais de acesso. Muitos processadores de texto, planilhas e EIS estão sendo construídos com interfaces SQL. Quase todos os fornecedores de BD relacionais embutem em seus pacotes suas próprias soluções de gerenciamento de interfaces e linguagem de 4a geração. 22 Declaração de Domínios Pela declaração de domínios pode-se dar um nome a um tipo de dados de tamanho especificado. Isto auxilia quando várias colunas tem características comuns. CREATE DOMAIN NÚMERO_EMP AS CHAR(5); A pré definição de um objeto de dados é útil para garantir que certa entrada em uma tabela tenha a forma dos dados esperados para essa coluna. CREATE DOMAIN NÚMERO_EMP AS CHAR(5) CHECK (VALUE IS NOT NULL); SQL possui dois tipos de strings: CHAR e VARCHAR. Se uma entrada for especificada como CHAR(N) e o string for menor do que N, os caracteres restantes recebem “branco”. Por outro lado VARCHAR sempre armazena exatamente o string recebido (não completa a cadeia de caracteres) e o tamanho da especificação de VARCHAR serve apenas para limite superior. Sempre que uma tabela fizer referência a outra é preciso definir anteriormente a tabela referenciada. Manipulação de Tabelas Para remover de um BD uma tabela EMPREGADOS o comando é: DROP TABLE EMPREGADOS; Para excluir uma coluna de uma tabela o comando é: ALTER TABLE EMPREGADOS DROP primeironome; Para adicionar uma coluna a uma tabela o que se faz é: ALTER TABLE EMPREGADOS ADD datanascimento DATE NOT NULL; Uma cláusula ALTER permite diversas alterações. DML Suponha-se que a criação de uma tabela foi feita da forma CREATE TABLE EMPREGADOS ( emp_número NUM(10) PRIMARY KEY, últimonome VARCHAR(20) NOT NULL, primeironome VARCHAR(20) NOT NULL, função VARCHAR(20) NOT NULL, departamento VARCHAR(20) ); A inclusão de uma linha pode ser feita da maneira que se segue. INSERT INTO EMPREGADOS VALUES ( ‘0466’, ‘Brito’, ‘Claudio’, ‘Marinheiro’, ‘‘ ); ou INSERT INTO EMPREGADOS (emp_número, últimonome, primeironome, função, departamento) 23 VALUES ( ‘0466’, ‘Brito’, ‘Claudio’, ‘Marinheiro’, ‘‘ ); ou ainda INSERT INTO EMPREGADOS (emp_número, últimonome, primeironome, função) VALUES ( ‘0466’, ‘Brito’, ‘Claudio’, ‘Marinheiro’ ); Para excluir todos os dados de uma tabela usa-se DELETE. DELETE FROM EMPREGADOS; Para exclusões seletivas deve-se especificar o critério de exclusão pela cláusula WHERE. DELETE FROM EMPREGADOS WHERE emp_número = ‘0406’; Pode-se fazer exclusões simultâneas de mais de uma tabela. DELETE FROM EMPREGADOS, GERAL WHERE emp_número = ‘0406’; A atualização é feita utilizando UPDATE e SET. UPDATE EMPREGADOS SET primeironome = ‘Manoel’ WHERE emp_número = ‘0394’; ou UPDATE EMPREGADOS SET primeironome = ‘Manoel’, função = ‘Mecânico’ WHERE emp_número = ‘0394’; DQL A sintaxe do comando SELECT é: SELECT nomes_das_colunas FROM nomes_das_tabelas [WHERE predicados_das_condições] [GROUP BY nomes_das_colunas] [HAVING condição] [ORDER BY nome_de_coluna]. As condições podem ser {BETWEEN, IN, LIKE, IS NULL, NOT, AND, OR, !=, >, >=, <=,<}. As funções de agregaçãoou de conjunto são seguidas do nome de uma coluna a qual elas se aplicam. O nome da coluna vem entre parênteses e essas funções são: Função Retorno COUNT Número de valores de uma coluna SUM Soma dos valores de uma coluna/expressão AVG Média dos valores de uma coluna/expressão MAX Maior valor em uma coluna MIN Menor valor em uma coluna A diferença entre asa cláusulas HAVING e WHERE é que a condição de busca WHERE se aplica a linhas isoladas antes do agrupamento, enquanto que a condição de busca da cláusula HAVING se aplica a grupos de linhas. Quando se usa a cláusula GROUP BY a cláusula HAVING se aplica a cada um dos grupos formado com valores iguais na coluna especificada para o grupamento. Caso não exista uma cláusula GROUP BY então .a cláusula HAVING aplica-se a toda a tabela. Se duas tabelas possuem, cada qual, uma coluna com um domínio comum, estas tabelas podem ser unidas por uma operação de junção com base nas colunas definidas sobre o domínio comum. A operação de 24 junção retorna uma nova tabela da qual cada linha é produto da concatenação de uma linha de cada uma das tabelas que contribuíram para a operação de junção. As linhas contribuintes foram selecionadas pelos seus valores na colunas de domínio comum. Junções nas quais a condição de junção é baseada na igualdade são chamadas de equi-junções que caracterizam-se por gerar tabelas que possuem duas colunas idênticas. Quando se elimina a duplicidade de colunas por uma operação de projeção a junção se torna uma junção natural. Quando se deseja obter e combinar o resultado de diversas consultas usa-se a união de tabelas. Quando se utiliza uma operação de união a linguagem SQL automaticamente elimina as duplicatas sem necessidade de tornar explícita a cláusula Distinct. Nas situações nas quais uma chave primária está relacionada com uma chave estrangeira e, esta chave estrangeira possa ser nula para algum valor da chave primária o efeito combinado da união poderia ficar comprometido. Considere-se, por exemplo, uma tabela na qual a chave primária fosse vendedor e outra tabela na qual a chave primária fosse cliente e, nesta última o vendedor fosse um atributo. Caso um vendedor estivesse sem cliente ele não apareceria na tabela de clientes. Para que uma junção de tabelas na qual as tuplas de uma tabela sem correspondência na outra apareçam no resultado concatenadas com uma tupla nula cria-se o conceito de junção externa. Para recuperar toda uma tabela escreve-se select from empregados; Para obter a lista dos empregados do departamento comercial escreve-se select from empregados where departamento = ‘Comercial’; Para obter esta lista classificada em ordem ascendente de sobrenome escreve-se select from empregados where departamento = ‘Comercial’ order by últimonome; Para desta lista recuperar apenas os números dos empregados escreve-se select emp_número from empregados where departamento = ‘Comercial’ order by últimonome; Para obter a lista dos empregados chamados José Silva escreve-se select from empregados where (primeironome = ‘José’) and (últimonome = ‘Silva’); Para obter todos os dados das tabelas EMPREGADOS e GERAL escreve-se select empregados., geral. from empregados, geral; Para obter os salários do pessoal do departamento comercial, sabendo que os salários ficam na tabela GERAL escreve-se select g.salário from empregados e, geral g where e.departamento = ‘Comercial’ and g.emp_número = e.emp_número; Verificar quem ganha mais de R$2.500,00 pode ser feito da forma select salário from geral where salário > 2.500; Verificar quem ganha mais de R$2.500,00 no departamento comercial pode ser feito da forma select g.salário from empregados e, geral g where e.departamento = ‘Comercial’ and g.emp_número = e.emp_número and g.salário > 2.500; A média salarial desse departamento pode ser obtida utilizando-se AVG. select avg (g.salário) 25 from empregados e, geral g where e.departamento = ‘Comercial’ and g.emp_número = e.emp_número; Segunda Lista de Exemplos EMP (EMP_#, EMP_NOME, DEPTO_#, CARGO, GERENTE, SALÁRIO) DEPTO (DEPTO_#, DEPTO_NOME, CIDADE) EMPREGO (DEPTO_#, PEÇA) ABASTECIMENTO (FORNEC, PEÇA) Q2 - Listar os diferentes números de departamentos da relação Emp SELECT UNIQUE DEPTO_# FROM EMP; Q3 - Listar os nomes dos empregados dos departamentos 25, 47 e 53 SELECT EMP_NOME FROM EMP WHERE DEPTO_# IN (25, 47, 53); alternativa WHERE (DEPTO_# = 25) (DEPTO_# = 47) (DEPTO_# = 53); M3 - Aumentar em 10% os salários dos empregados que ganham menos de R$10.000,00 UPDATE EMP SET SALÁRIO = SALÁRIO1.1 WHERE SALÁRIO < 10000 Terceira Lista de Exemplos Como exemplo da linguagem SQL serão resolvidos os problemas utilizados na apresentação da Álgebra Relacional. Para selecionar as tuplas da relação empréstimos aonde a filial seja “Madureira”, escreve-se select * from emprestimos where nome_f = 'Madureira'; Para obter os clientes que tenham o mesmo nome que seus gerentes pode-se escrever select * from clientes where nome_c = gerente; Para encontrar os clientes do gerente “João” e a cidade na qual eles vivem necessita-se de informações das relações correntistas e clientes e pode-se escrever select correntistas.nome_c, correntistas.cidade_c from clientes, correntistas where clientes.nome_c = correntistas.nome_c and gerente = 'João'; Para encontrar os nomes dos correntistas que moram na mesma cidade e na mesma rua que Pedro escreve-se 26 select nome_c from correntistas where rua in (select rua from correntistas where nome_c = 'Pedro') and cidade_c in (select cidade_c from correntistas where nome_c = 'Pedro'); Para encontrar os usuários da agência Madureira é preciso encontrar todos aqueles que ou tenham conta na agência ou que tenham feito empréstimos lá, escrevendo-se select emprestimos.nome_c from emprestimos where emprestimos.nome_f = 'Madureira' union all select depositos.nome_c from depositos where depositos.nome_f = 'Madureira'; ou select e.nome_c from emprestimos e where e.nome_f = 'Madureira' union all select d.nome_c from depositos d where d.nome_f = 'Madureira'; Para encontrar os usuários do banco que na agência Madureira tenham conta corrente mas não tenham empréstimos pode-se escrever select depositos.nome_c from depositos where depositos.nome_f = 'Madureira' minus select emprestimos.nome_c from emprestimos where emprestimos.nome_f = 'Madureira'; Para encontrar o maior saldo dentre as contas correntes do banco o que se faz é select saldo from depositos where saldo in (select max(saldo) from depositos); Para obter todos os usuários que possuam tanto empréstimos quanto contas correntes no banco escreve-se select correntistas.nome_c, correntistas.cidade_c from correntistas, emprestimos where correntistas.nome_c = emprestimos.nome_c; Para encontrar os usuários que possuem empréstimos no banco e as cidades em que moram é necessário utilizar as relações empréstimos e correntistas, de uma das formas abaixo select correntistas.nome_c, correntistas.cidade_c from correntistas, emprestimos where correntistas.nome_c = emprestimos.nome_c; Para encontrar todos os usuários que possuem contas em todas as agências situadas no Rio de Janeiro é necessário mudar a frase para “encontrar todos os usuários para os quais não exista uma filial para a qual não exista um depósito do mesmo usuário”, da forma select df.nome_c, df.nome_f from depositos df where not exists (select * from filiais where cidade_f = 'Rio de Janeiro' and not exists (select * from depositos dd where dd.nome_c= df.nome_c and dd.nome_f = filiais.nome_f)); ou da forma select nome_c, nome_f from depositos df 27 where not exists (select * from filiais where cidade_f = 'Rio de Janeiro' and not exists (select * from depositos where nome_c = df.nome_c and nome_f = filiais.nome_f)); Outra solução pode ser obtida usando minus, da forma select distinct s.nome_c, s.nome_f from depositos s where not exists ((select nome_f from filiais where cidade_f = 'Rio de Janeiro') minus (select t.nome_f from depositos t where s.nome_c = t.nome_c)); 28 SQL Embutida A SQL embutida fornece um meio para construir a consulta necessária num programa de computador e torna possível escrever o programa sem que se saiba nada a respeito da maneira como os dados estão armazenados. Em outras palavras, a SQL embutida mantém os ideais dos bancos de dados relacionais e das linguagens de consulta como SQL. Está ao encargo do programador fornecer as variáveis da linguagem hospedeira para os resultados das consultas ou para os valores variáveis das condições da linguagem da consulta. Estas últimas são às vezes chamadas de variáveis de ligação. Adotar-se-á o termo variáveis de ligação para tais variáveis. Para o texto que se segue seá utilizado um Banco de Dados Judiciário, cujas relações são definidas como se segue. ID (número_de_registro, nome_do_prisioneiro, identificação_do_prisioneiro) APELIDO (identificação_do_prisioneiro, apelido_do_prisioneiro) NASCIMENTO (identificação_do_prisioneiro, data_do_nascimento) PRISÃO (número_de_registro, data_da_prisão, pena) Reconhecendo Comandos SQL Embutidos Todos os comandos SQL embutidos são precedidos pelas palavras-chave EXEC SQL. Dependendo da linguagem de programação hospedeira, eles são encerrados por um ponto e vírgula ou algum outro terminador, ou até mesmo sem nenhum terminador em particular. Uma Primeira Visão da SQL Embutida Com a utilização das palavras-chave EXEC SQL para iniciar e do ponto e vírgula para encerrar, muitos comandos SQL podem ser embutidos na linguagem hospedeira simplesmente pela sua inclusão no programa, como, por exemplo: exec sql update prisão set pena = ‘dirigir embriagado’ where identificação_do_prisioneiro = 111111; ou exec sql delete from prisão where identificação_do_prisioneiro = 111111; Variáveis da Linguagem Hospedeira na SQL Embutida Variáveis da linguagem de programação hospedeira devem aparecer em comandos SQL embutidos. Assim, um formato para o comando SELECT na SQL embutida é: exec sql select < lista-objetivo > into < variáveis da linguagem hospedeira > from where ; 29 Um exemplo específico deste formato é: exec sql select pena into: cadeia from prisão where número_de_registro = : variável_hospedeira; Este formato é aceitável se a consulta retorna apenas uma linha. Caso contrário, é necessária uma área de trabalho. Na SQL embutida, a área de trabalho é chamada de cursor. No último exemplo, cadeia e variável_hospedeira são variáveis da linguagem hospedeira. Em algumas implementações, todas as variáveis da linguagem hospedeira usadas numa expressão SQL embutida devem ser precedidas por dois pontos ( : ) para diferenciá-las dos nomes das colunas. Declaração de Variáveis As variáveis da linguagem hospedeira que são usadas em comandos EXEC SQL devem aparecer numa seção de declaração no local apropriado do programa hospedeiro. O formato é EXEC SQL BEGIN DECLARE, seguido das declarações das variáveis, que são então seguidas de EXEC SQL END DECLARE. SELECT na SQL Embutida O formato do SELECT é: exec sql select ... into [lista de variáveis da linguagem hospedeira] from ...where...; Por exemplo: exec sql select nome_do_prisioneiro into :cadeia from id where número_de_registro = 111111; ou exec sql select nome_do_prisioneiro into :cadeia from id where número_de_registro = :variável_hospedeira; UPDATE em SQL Embutida O formato do UPDATE na SQL embutida é: exec sql update id set nome_do_prisioneiro = ‘Manoel de Almeida’ where número_de_registro = 111111; exec sql update id set nome_do_prisioneiro = ‘Manoel de Almeida’ where número_de_registro = :variável_hospedeira; exec sql update id set nome_do_prisioneiro = variável_hospedeira_1 where número_de_registro = :variável_hospedeira_2; DELETE e INSERT na SQL Embutida As variáveis da linguagem hospedeira podem ser usadas onde for apropriado. Eis um exemplo: exec sql delete from prisão where pena = :variável_hospedeira; exec sql insert into prisão (número_de_registro, pena) values (:variável_hospedeira_1, :variável_hospedeira_2); 30 Outros Comandos SQL Embutidos As regras para os comandos de bloqueio e para os comandos COMMIT WORK e ROLLBACK WORK são exatamente as mesmas que as da SQL não embutida, exceto que eles devem ser precedidos por EXEC SQL e encerrados por um ponto e vírgula ( ; ). Cursores O resultado de uma consulta é uma tabela virtual ou uma visão. Em qualquer situação, os resultados de uma consulta conterão freqüentemente várias linhas com múltiplas colunas, que precisarão ser tratadas uma a uma num laço de programa. Uma vez que a maioria das linguagens de programação contém recursos para manipular arquivos, é razoável tratar o resultado da consulta de modo similar a um arquivo, que pode ser aberto, lido seqüencialmente, uma linha de cada vez, e fechado quando o fim do arquivo é alcançado. Tal entidade correspondente a um arquivo deveria ser chamada de cursor. O cursor deve ser associado a uma consulta. O formato para isto é: exec sql declare a cursor for [comando sql] O A na expressão acima é uma variável e pode ser substituído por qualquer nome, dependendo, é claro, das restrições que o projetista pode ter implementado para nome de cursor. O comando SQL entre colchetes tanto pode ser uma consulta SQL real como um ponteiro para uma cadeia de caracteres, isto é, um nome de variável da linguagem hospedeira apontando para uma cadeia de caracteres que contém um comando para uma consulta SQL. Após dar um nome ao seu cursor, pode-se abri-lo (como a um arquivo). O formato para isto é: exec sql open a; Para ler seu pseudo-arquivo cursor, há o comando FETCH...INTO com o formato exec sql fetch a into [lista de nomes de variáveis da linguagem hospedeira] (Há uma variável hospedeira para cada nome de coluna selecionada). Provavelmente, o comando FETCH ficará em algum tipo de laço na linguagem hospedeira por meio do qual cada linha é tratada na sua vez. É bom fechar o cursor, como é feito com arquivos, quando todas as leituras tiverem terminado. O formato para isto é: exec sql close a; O Uso de Cursores Para UPDATE e DELETE Finalmente, observa-se que um cursor pode ser usado para atualizar ou eliminar certas linhas, dependendo dos valores dessas linhas. O formato para o DECLARE nesse caso é: exec sql declare a cursor for select...... where...... for update of < nome da coluna >; As linhas do cursor estão ordenadas, seja por uma cláusula ORDER BY ou por algum outro valor suposto. Cada FETCH move então a posição corrente para a frente uma linha e o UPDATE ou o DELETE podem operar na linha corrente. Depois que o cursor for fechado, um EXEC SQL COMMIT WORK efetivará no banco de dados as modificações feitas no cursor. O formato para atualizar um cursor é: exec sql update < nome da tabela > set < nome da coluna > = < variável_hospedeira > where current of a; O nome da coluna acima deve ser o mesmo nome da coluna do DECLARE. De modo semelhante, o formato para eliminação de linha num cursor é: exec sql deletefrom < nome da tabela > where current of a; 31 Todos os comandos SQL que não envolvam matrizes podem ser embutidos, bastando precedê-los por EXEC SQL e encerrá-los por um ponto e vírgula. Na existência de matrizes, os cursores podem ser usados como mostrado nos exemplos acima.
Compartilhar