SQL DDL Básico (Manipulando Objetos do BD)

Criando um Banco de Dados (CREATE DATABASE)

Utilizando o IBOConsole esta operação já foi explicada em seu pequeno tutorial, que você pode acessar aqui. Para criar “na mão grande”, ou para utilização em um script de criação de banco, utilizamos a sintaxe a seguir do comando CREATE DATABASE (a sintaxe é simplificada):

CREATE DATABASE "CAMINHO\NOME_DO_BANCO.FDB";

Por exemplo, criando o banco de dados do DEVA no diretório C:\BANCO:

CREATE DATABASE "C:\BANCO\DEVA.FDB";

Se quiser utilizar o banco através do IBOConsole, não deixe de registrá-lo (lembre aqui como fazê-lo.

Conectando a um Banco de Dados (CONNECT)

Ao clicar duas vezes num Banco de Dados no IBOConsole, internamente estaríamos conectando ao banco de dados com o comando CONNECT:

CONNECT "CAMINHO\NOME_DO_BANCO.FDB" USER "USUARIO" PASSWORD "SENHA";

Por exemplo, criando o banco de dados do DEVA no diretório C:\BANCO:

CONNECT "C:\BANCO\DEVA.FDB" USER "SYSDBA" PASSWORD "masterkey";

Importante: o usuário não é case sensitive, mas a senha é. Em bom português, não faz diferença se você digita o usuário em maiúsculas ou minúsculas, mas a senha precisa ser digitada como foi criada.

  • Usuário SYSDBA ou sysdba não faz diferença, mas;
  • Senha masterkey ou MASTERKEY faz muita diferença

O comando CONNECT tem mais sentido num script ou utilizando o ISQL em modo texto, mas importante conhecê-lo exatamente para editar scripts que executam comandos em lote.

Criando Tabelas (CREATE TABLE)

Antes de criar tabelas, é preciso conhecer os Tipos de Campos (ou Domínios) disponíveis no FIREBIRD.

Observação: uma explicação detalhada sobre este assunto é encontrado na Apostila Firebird 1.0.

Tipos de Dados (Domínios Padrão) do FIREBIRD

  • CHAR(n) - String (texto) de tamanho fixo “n”. Limite 32767,32k. Usado quando o texto armazenado é sempre do mesmo tamanho, como em UF, CPF, CEP
  • VARCHAR(n) - String (texto) de tamanho variável até o máximo de “n”. Limite 32767,32k. Usado quando não se sabe o tamanho exato do texto a ser armazenado, mas apenas seu tamanho máximo, como em Nome, Endereço, etc.
  • DATE - Data (o formato armazenado é aaaa-mm-dd, ou 2000-12-31 para 31 de dezembro de 2000)
  • TIME - Hora
  • TIMESTAMP - Data e Hora Simultaneamente
  • DECIMAL(n,d) ou NUMERIC(n,d) - números com precisão decimal (n - antes da vírgula, d - casas decimais)
  • SMALLINT - Dados numéricos inteiros pequenos, na faixa de -32768 a 32767.
  • INTEGER - Dados numéricos inteiros grandes (32bits), na faixa de -2.147.483.648 até

2.147.483.648

  • FLOAT - Dados numéricos com precisão simples de 7 dígitos (casas decimais).
  • DOUBLE PRECISION - Dados numéricos que exigem grande precisão (casas decimais). 64 bits.
  • BLOB - Este tipo de campo é o tipo indicado para armazenar Textos Grandes “Memos”, Fotos, Gráficos, Ícones, isto é, aparentemente não tem um tipo de dado que não possa ser armazenado no Campo Blob. Campos Blob´s não podem ser indexados. Limite: 64k. Subtipos:
    • SUB_TYPE 0 - Formatos binários: fotos, sons, etc;
    • SUB_TYPE 1 - Textos

Sintaxe CREATE TABLE (Criar Tabela)

A criação de uma tabela simples segue a sintaxe abaixo:

CREATE TABLE NOMETABELA(
NOMECAMPO1 TIPO,
NOMECAMPO2 TIPO,
NOMECAMPO3 TIPO,
NOMECAMPO4 TIPO
);

Perceba que a lista dos campos está envolvida em parenteses, e que após cada campo há uma vírgula (,), e após o último campo não há. Um exemplo:

CREATE TABLE CLIENTE (
CODIGO INTEGER,
NOME VARCHAR(40),
TIPO INTEGER,
ENDERECO VARCHAR(70),
CIDADE VARCHAR(40),
UF CHAR(2),
OBSERVACAO BLOB SUB_TYPE 1,
DATANASCIMENTO DATE,
DATACADASTRO DATE
);

Opções comuns para campos na criação de tabelas

Além da definição do tipo, algumas opções são comumente utilizadas na criação de campos nas tabelas. Vejamos os mais comuns:

  • NOT NULL: NÃO NULO Utilizado para forçar que o campo seja sempre preenchido com um valor, não sendo permitidos valores nulos. SEMPRE necessário quando a o campo é chave primária.
  • DEFAULT: Valor Padrão Utilizado para informar um valor padrão para o campo. Pode ser utilizada uma função, com será visto mais tarde, para determinar o valor
CREATE TABLE CLIENTE (
CODIGO INTEGER NOT NULL,
TIPO INTEGER NOT NULL,
NOME VARCHAR(40) NOT NULL,
ENDERECO VARCHAR(70),
CIDADE VARCHAR(40),
UF CHAR(2) DEFAULT 'BA',
OBSERVACAO BLOB SUB_TYPE 1,
DATANASCIMENTO DATE,
DATACADASTRO DATE
);

Criando chaves primárias (PK - Primary Key)

A criação de chaves primárias é feita logo após a lista de campos. A sintaxe é:

PRIMARY KEY (campo)
PRIMARY KEY (campo1,campo2) -> para chaves compostas
);

Exemplo:

CREATE TABLE CLIENTE (
CODIGO INTEGER NOT NULL,
NOME VARCHAR(40) NOT NULL,
TIPO INTEGER NOT NULL,
ENDERECO VARCHAR(70),
CIDADE VARCHAR(40),
UF CHAR(2) DEFAULT 'BA',
OBSERVACAO BLOB SUB_TYPE 1,
DATANASCIMENTO DATE,
DATACADASTRO DATE,
PRIMARY KEY (CODIGO)
);

Criando chaves estrangeiras (FK - Foreing Key)

A criação de chaves primárias é feita logo também após a lista de campos. A sintaxe é:

/* Sintaxe básica*/
FOREIGN KEY (campo) REFERENCES tabela_estrangeia(campo_tabela_estrangeira)
/* Sintaxe Extendida */
FOREIGN KEY (campo) REFERENCES tabela_estrangeia(campo_tabela_estrangeira) ON UPDATE {action} ON DELETE {action}
);

Na sintaxe extendida, define-se o que acontecerá com o registro desta tabela se acontecer a atualização da chave estrangeira (ON UPDATE) ou na exclusão do registro correspondente na tabela estrangeira (ON DELETE). Vejamos os resultados:

  • NO ACTION (Sem ação) - Não faz nada, apenas impede a ação (restrição de alteração ou exclusão da chave na tabela estrangeira);
  • CASCADE (cascatear) - No caso de atualização da chave na tabela estrangeira, atualiza nesta tabela; no caso de exclusão do registro na tabela estrangeira, EXCLUI TODOS OS REGISTROS RELACIONADOS NESTA TABELA (note que pode ser útil ou perigoso…);
  • SET DEFAULT (define padrão) - Define para um valor padrão aqui informado em caso de alteração ou exclusão da chave na tabela estrangeira;
  • SET NULL (define para nulo) - Define para nulo em caso de alteração ou exclusão da chave na tabela estrangeira.

Só é possível criar uma chave estrangeira se já houver sido criada a tabela estrangeira.

CREATE TABLE TIPOCLIENTE (
CODIGOTIPO INTEGER NOT NULL,
DESCRICAO VARCHAR(20),
PRIMARY KEY (CODIGOTIPO)
);
 
CREATE TABLE CLIENTE (
CODIGOCLIENTE INTEGER NOT NULL,
NOME VARCHAR(40) NOT NULL,
TIPO INTEGER NOT NULL,
ENDERECO VARCHAR(70),
CIDADE VARCHAR(40),
UF CHAR(2) DEFAULT 'BA',
OBSERVACAO BLOB SUB_TYPE 1,
DATANASCIMENTO DATE,
DATACADASTRO DATE,
PRIMARY KEY (CODIGOCLIENTE),
FOREIGN KEY (TIPO) REFERENCES TIPOCLIENTE (CODIGOTIPO)
);

Chaves Primárias Autonumeradas

Alguns bancos como o MS Access ou o MySQL possuem parâmetros simples para criar campos autonumerados, muito úteis para chaves primárias. Mas no FIREBIRD o trabalho é maior.

Um dos objetos existente no FIREBIRD é o GENERATOR (algo como “Gerador”), que nada mais é que um acumulador de um número inteiro. Uma técnica simples para criar um campo autonumerado é utilizar o objeto TRIGGER (Gatilho), que executa uma ação vinculada a um evento na tabela.

O truque é o seguinte:

CREATE GENERATOR {TABELA}_GEN;
SET TERM ^ ;
CREATE TRIGGER "TRIG_{TABELA}_GEN" FOR "CLIENTE" 
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  IF (new.{CAMPOCHAVE} IS NULL) then 
    begin
      new.{CAMPOCHAVE} = gen_id( {TABELA}_GEN, 1 );
    end
end
 ^
COMMIT WORK ^
SET TERM ;^

Sendo:

  • {TABELA} = Tabela a criar a autonumeração
  • {CAMPOCHAVE} = Chave Primária da Tabela

Exemplo para tabela cliente que estamos criando:

CREATE GENERATOR CLIENTE_GEN;
SET TERM ^ ;
CREATE TRIGGER "TRIG_CLIENTE_ID" FOR "CLIENTE" 
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  IF (new.CODIGOCLIENTE IS NULL) then 
    begin
      new.CODIGOCLIENTE = gen_id( CLIENTE_GEN, 1 );
    end
end
 ^
COMMIT WORK ^
SET TERM ;^

Alterando TABELAS (ALTER TABLE)

O comando ALTER TABLE é utilizado e conjunto com a sintaxe de criação:

/* Incluindo um campo */
ALTER TABLE NOMETABELA ADD NOVOCAMPO5 TIPO;
 
/* Excluindo um campo */
ALTER TABLE NOMETABELA DROP NOVOCAMPO5;
 
/* Incluindo e excluindo ao mesmo tempo
ALTER TABLE NOMETABELA DROP NOVOCAMPO5, */
      ADD NOVOCAMPO6 TIPO;
 
/* Alterando o nome de um campo */
ALTER TABLE NOMETABELA ALTER CAMPO5 TO CAMPO6;
 
/* Adicionando uma chave primária */
ALTER TABLE NOMETABELA ALTER PRIMARY KEY (CAMPO1);
 
/* Adicionando uma chave estrangeira */
ALTER TABLE NOMETABELA ALTER FOREIGN KEY (CAMPO1) REFERENCES TABELAESTRANGEIRA (CAMPOCHAVE);

Alguns exemplos:

/* Incluindo um campo */
ALTER TABLE CLIENTE ADD EMAIL VARCHAR(30) NOT NULL;
 
/* Excluindo um campo */
ALTER TABLE CLIENTE DROP LOGRADOURO;
 
/* Incluindo e excluindo ao mesmo tempo */
ALTER TABLE CLIENTE ADD EMAIL VARCHAR(30) NOT NULL, DROP LOGRADOURO;
 
/* Alterando o nome de um campo */
ALTER TABLE CLIENTE ALTER LOGRADOURO TO ENDERECO;
 
/* Adicionando uma chave primária */
ALTER TABLE CLIENTE ALTER PRIMARY KEY (CODIGO);
 
/* Adicionando uma chave estrangeira */
ALTER TABLE CLIENTE ALTER FOREIGN KEY (CODTIPOCLIENTE) REFERENCES TIPOCLIENTE (CODTIPOCLIENTE);

Excluindo TABELAS, BANCOS e outros objetos

O comando de exclusão é o DROP. Ele pode ser executado para vários objetos:

/* Excluindo uma tabela */
DROP TABLE nome_da_tabela;
 
/* Excluindo um generator */
DROP GENERATOR nome_da_tabela;
 
/* Excluindo uma TRIGGER */
DROP TRIGGER nome_trigger
 
/* Excluindo um banco */
DROP DATABASE "CAMINHO\NOME_DO_BANCO.FDB";

Exclusão é algo radical, em especial de bancos inteiros. Deve ser realizada com cuidado. Após a confirmação da transação (COMMIT), não haverá volta, a não ser por backup.