Structure Query Language SQL Guilherme Pontes lf.pontes.sites.uol.com.br 1. Domínio dos Atributos Por domínio, ou tipo, pode-se entender como a maneira como determinado atributo (ou campo, se tratando de tabelas) armazena seu dado. Em melhores palavras, cada atributo possui a capacidade de armazenar um dado pertinente a uma linha (tupla) da tabela. Que dado é esse? Dados como código, CPF, nome, preço, quantidade, entre outros, são geralmente armazenados e gerenciados pelos SGBD s. A maneira como o atributo nome armazena seus caracteres difere da maneira como o preço guarda seu valor. Essa maneira, ou forma de armazenamento é definida pelo domínio do atributo. Em geral temos tipos como CHAR, para armazenamento de caracteres, NUMBER, para números, DATE para datas, entre outros. Cada SGBD s, apesar de trabalhar com SQL, possui seus próprios tipos de dados. Veremos adiante alguns dos muitos tipos oferecidos por três bases: Oracle 10g, MySQL e Firebird. Onde vou especificar o tipo do atributo? Durante o processo de criação/modificação das tabelas, o domínio deverá ser especificado logo após a definição do nome do atributo. Domínio dos Atributos no MySQL Sua ideologia é oferecer aos desenvolvedores uma ferramenta rápida e simplificada, se comparada aos SGBD s existentes, contudo, o MySQL, ainda assim oferece uma grande variedade de tipos. Veremos abaixo os principais. O MySQL oferece vários tipos numéricos, contudo, aqui, trabalharemos com apenas alguns deles. Para maiores esclarecimentos, consulte http://www.mysql.com. Integer Float Double Número inteiro com (default do campo) ou sem sinal (acrescido da sintaxe unsigned). No primeiro caso, varia de -2147483648 até 2147483647. Sem a presença do sinal, a margem de valores é de 0 até 429.496.295. Número com vírgula de pequena precisão. Pode ou não conter o sinal. Número com vírgula de grande precisão. Trabalha com ou sem a presença da sintaxe unsigned (sem sinal). 8 bytes
Numeric(M,D) Número que varia sua precisão de acordo com a definição do usuário. M representa a quantidade total (à esquerda e direita da vírgula) de elementos. D representa o número de casas decimais. M+2 bytes (se D > 0) ou M+1 byte (se D = 0) De forma análoga, focaremos nosso estudo em apenas alguns tipos usados para armazenar data/hora. Date Armazena datas variando entre 01/01/1001 à 31/12/9999. Deve-se ter atenção a inclusão (conceito abordado futuramente) de dados. O formato a ser seguido entre aspas é: aaaa/mm/dd. 3 bytes DateTime Time Usado para armazenar data e hora que varie entre 01/01/1001 às 0 horas, 0 minutos e 0 segundos à 31/12/9999 às 23 horas, 59 minutos e 59 segundos. Seu formato é aaaa/mm/dd hh:mm:ss e deve ser usado entre aspas. Armazena uma hora que obedece ao seguinte formato (entre aspas): hh:mm:ss 8 bytes 3 bytes Por fim, para armazenamento de seqüência de caracteres, temos: Char(n) VarChar(n) Armazena n caracteres. Neste caso, quando especificamos um valor para n, o campo sempre ocupará n bytes mesmo que estes não sejam usados. Por exemplo: um Char(10) armazenando o texto casa ocupa 10 bytes, mesmo casa contendo 4 caracteres. n varia de 0 a 255. Armazena n caracteres, contudo, ocupa exatamente a quantidade de caracteres usados (acrescidos de um). Quando temos VarChar(10) armazenando casa, este campo ocupa 5 bytes. n bytes n+1 bytes Text Um texto com no máximo 65535 caracteres. Tamanho do texto + 2 bytes
Domínio dos Atributos no Firebird O Firebird também nos oferece quase todos os dados suportados pela padronização SQL. Veremos abaixo alguns dos principais tipos suportados. Em geral, alguns tipos são análogos aos suportados pelo MySQL. Integer Número inteiro. Apresenta uma variação que vai de -2147483648 a 2147483647. O Firebird não oferece o recurso unsigned. Float Número com vírgula de precisão simples. Double Precision Número com vírgula de alta precisão. 8 bytes Numeric(M,D) Date Número de M elementos e D casas decimais. M, por especificar o total de elementos, sempre será maior que D. Armazena datas obedecendo o formato, entre aspas: mm/dd/aaaa. M+2 bytes (se D > 0) ou M+1 byte (se D = 0) Time Armazena hora no formato: hh:mm:ss. TimeStamp Char(n) VarChar(n) Armazena hora e data. Deve ser inserido com aspas e obedece ao seguinte formato: mm/dd/aaaa hh:mm:ss Seqüência de n caracteres de tamanho fixo. Se definirmos 30 caracteres, o campo ocupará 30 bytes em qualquer situação. n varia de 0 a 32767. Armazena n caracteres, sendo o máximo 32767. Seu tamanho varia de acordo com os caracteres ocupados mais um, ou seja, se temos VarChar(5) armazenando o texto ab, estamos ocupando 3 bytes. n bytes n+1 bytes Para maiores esclarecimentos, consulte http://www.firebirdsql.org. Domínio dos Atributos no Oracle O Oracle facilita a escolha do domínio do atributo, pois trabalha com poucos tipos. Contudo, isso não limita a variação de armazenamento, pois cada um dos tipos engloba várias possibilidades.
Tipo Number(P,S) Date TimeStamp Char(n) Descrição É capaz de armazenar números inteiros ou de ponto flutuante (com casas decimais). P representa a precisão, ou seja, o total de elementos que o número conterá somando as casas decimais. S é a escala e representa a número de casas decimais. Usado para armazenar datas. Obedece ao formato dd/mm/aaaa e deve estar compreendido entre aspas. É usado para armazenar data e hora. Seu formato deve obedecer a seguinte sintaxe: TIMESTAMP'aaaa-mm-dd hh:mm:ss' Observe também o uso das aspas. Usado para armazenar caracteres de tamanho fixo. Deve conter no máximo (n) 2000 elementos. Este domínio ocupará sempre o valor estipulado em n, independente do uso destes espaços. Varchar2(n) Armazena n caracteres. Suporta no máximo 4000 letras. Esta seqüência de caracteres não possui tamanho fixo, ou seja, mesmo definido varchar2 (1000), o campo ocupará somente o espaço utilizado. Para maiores referências, consulte http://www.oracle.com. Estes são os principais tipos adotados nos SGBD s acima citados. Veremos agora, os comandos básicos de criação/manutenção das tabelas de uma base de dados. 2. Criação/Alteração/Exclusão de Tabelas Com um banco de dados criado, o próximo passo é referente à manutenção das tabelas. Em geral, todos os SGBD s trabalham com os mesmos comandos de criação/alteração/exclusão, variando apenas na definição dos domínios dos atributos. O estudo aqui apresentado centrase na manutenção por meio de comandos SQL e não aborda a adoção de ferramentas de interação facilitada (como a oferecida pelo Oracle 10g, por exemplo). Em primeiro lugar, veremos a criação de tabelas. Criação de Tabelas: O processo de criação de tabelas segue, em geral, a sintaxe apresentada abaixo. create table nome_da_tabela ( nome_do_atributo1 tipo restricoes, nome_do_atributo2 tipo restricoes,... constraints );
O processo de criação envolve a nome da tabela e os atributos (acompanhados ou não de restrições de integridade). Pode-se também acrescentar a cláusula constraint. Para facilitar o entendimento, observe o diagrama de estrutura de dados a seguir. Por conveniência, mostraremos a criação das tabelas acima em apenas um SGBD, neste caso, o MySQL. Para adaptar os comandos descritos, deve-se apenas substituir os domínios do MySQL para tipos equivalentes nos outros SGBD s. Criando a tabela clientes no MySQL: 1 create table clientes ( 2 codigo integer not null, 3 nome varchar(60) not null, 4 CPF char(14) unique not null, 5 telefone char(14), 6 constraint pk_clientes primary key (codigo) 7 ); Observe que, em quase todos os casos, a cláusula not null está presente inclusive na chave primária. Na primeira linha temos o comando de criação seguido do nome da tabela. Nas linhas 2, 3, 4 e 5 definimos os campos. Por fim, na linha 6, através da cláusula constraint especificamos que codigo é uma chave primária. Todo comando create table guardará seus atributos entre parênteses. Criando a tabela dependentes no MySQL: 1 create table dependentes ( 2 cod_cliente integer not null, 3 CPF char(14) not null, 4 nome varchar(60) not null, 5 constraint pk_dependentes 6 primary key (cod_cliente,cpf), 7 constraint fk_dependentes foreign key (cod_cliente) references clientes(codigo) 8 ); Deve-se destacar a definição de uma chave primária composta e a presença da chave estrangeira cod_cliente (associada ao campo codigo da tabela clientes). Observe também que CPF, neste caso, não está restringido pela cláusula unique, pois a chave primária já garante existência exclusiva do campo.
O procedimento de alteração das tabelas, similarmente ao processo de criação, varia apenas os tipos dos campos. Em geral, os três SGBD s estudados apresentam a mesma sintaxe. Mudar o nome da tabela clientes para cli no MySQL: alter table clientes rename to cli; Mudar o nome do campo da tabela cli no MySQL: alter table cli change nome n varchar(60) not null; Neste caso, o campo nome foi renomeado para n. Observe que o tipo de a restrição deve ser repetida. Abaixo, temos um exemplo de modificação do tipo e restrição de um campo da tabela. Mudar o tipo do campo n da tabela cli no MySQL: alter table cli change n n char(40) unique not null; Adicionar um campo no MySQL: alter table cli add sexo char(1) check (sexo = M or sexo = F ); Excluir um campo no MySQL: alter table cli drop column sexo; Abaixo estamos adicionando uma nova restrição, contudo, deve-se observar que cli já possui uma chave primária. Este procedimento iria gerar um ERRO. Se, durante a criação da tabela clientes, a linha 7 fosse ignorada, este comando seria aceito. Adicionar restrição no MySQL: alter table cli add constraint pk_cli primary key (CPF); Por não envolver os domínios dos atributos, o procedimento de exclusão de tabelas é análogo em todos SGBD s. Deve-se observar que a base de dados não deixará ocorrer a exclusão da tabela cli antes que a tabela dependentes seja excluída. Isto ocorre graças a existência da chave estrangeira em dependentes referenciando cli. Excluindo uma tabela no MySQL: drop table dependentes; Através dos comandos apresentados, podemos criar nossa base de dados. Adiante, veremos os comandos de manipulação dos dados das tabelas.