terça-feira, 28 de junho de 2011

Stored Procedure para saber os aniversariantes por dia/mês


Administrador Essa procedure lhe retorna todos os aniversariantes de um determinado período de dia e mês. Foi feita originalmente para Firebird, mas pode ser facilmente adaptada para qualquer outro banco que suporte Stored Procedures

Observação: este artigo é uma alternativa ao material enviado pelo amigo cruzeirense, pois em sua dica, exige-se que o ano de nascimento também seja informado como parâmetro da procedure. Seu material pode ser visto neste link:

No exemplo, utilizarei uma tabela chamada FUNCIONARIO, conforme pode ser visto abaixo:

/* Estrutura da tabela FUNCIONARIO
CREATE TABLE FUNCIONARIO (
    ID               INTEGER,
    NOME             VARCHAR(50),
    SALARIO          NUMERIC(15,2),
    DATA_NASCIMENTO  TIMESTAMP
);
*/

SET TERM ^ ;

CREATE PROCEDURE ANIVERSARIANTES (
    strdta_ini varchar(5),
    strdta_fim varchar(5))
returns (
    nome varchar(50),
    salario numeric(15,2),
    dta_nasc timestamp)
as
declare variable dta_ini timestamp;
declare variable dta_fim timestamp;
BEGIN
    SELECT CAST(:STRDTA_INI||'.'||CAST(EXTRACT(YEAR FROM
        MAX(DATA_NASCIMENTO)) AS VARCHAR(10)) AS TIMESTAMP) AS B
        FROM FUNCIONARIO INTO DTA_INI;
    SELECT CAST(:STRDTA_FIM||'.'||CAST(EXTRACT(YEAR FROM
        MAX(DATA_NASCIMENTO)) AS VARCHAR(10)) AS TIMESTAMP) AS B
        FROM FUNCIONARIO INTO DTA_FIM;
    WHILE (DTA_INI <= DTA_FIM) DO
    BEGIN
        FOR SELECT NOME, SALARIO, DATA_NASCIMENTO FROM FUNCIONARIO WHERE
        EXTRACT(DAY FROM DATA_NASCIMENTO) = EXTRACT(DAY FROM :DTA_INI) AND
        EXTRACT(MONTH FROM DATA_NASCIMENTO) = EXTRACT(MONTH FROM :DTA_INI)
        ORDER BY NOME, DATA_NASCIMENTO INTO :NOME, :SALARIO, :DTA_NASC DO
            SUSPEND;
        DTA_INI = DTA_INI + 1;
    END
END^

SET TERM ; ^

Agora é só fazer um select como o abaixo e pronto! ;-)

SELECT * FROM ANIVERSARIANTES('01/01', '31/01');

Migração de dados entre bancos ou tabelas


Administrador Esta é uma dica simples de como fazer migração de dados entre bancos ou entre tabelas diferentes, utilizando poucas linhas de código e deixando o trabalho maior na organização dos componentes

Você deve deixar os campos com as mesmas posições em seus componentes DataSet de origem e destino (componentes que farão a leitura de uma tabela e edição na outra). Este DataSet, obviamente pode ser um TQuery, TTable, TIBQuery, TADOQuery, TClientDataSet ou, enfim, qualquer outro componente descendente da classe TDataSet.

Vamos supor que estamos fazendo a migração de um banco Access para Firebird. Para acessar o Access, usaremos um ADOQuery, e para Firebird, ClientDataSet.

Feitas as conexões, o que precisamos fazer é organizar os campos no ADOQuery e no ClientDataSet para que fiquem com as mesmas posições, ou seja, campo[0] do ADOQuery equivale ao campo[0] no ClientDataSet, assim como os demais, campo[1], campo[2], etc.

Organizados os campos, o seguinte código seria suficiente para transferir os dados entre as tabelas:

//código do botão "Transferir"
var
  c: integer;
begin
  //abre a tabela Destino
  ClientDataSet1.Open;
  //abre a tabela Origem
  ADOQuery1.Open;
  //enquanto não chegar ao fim da origem
  while not ADOQuery1.EOF do
  begin
    //abre um novo registro no destino
    ClientDataSet1.Append;
    //para cada campo da tabela destino
    for c := 0 to ClientDataSet1.FieldCount-1 do
      //preenche cada campo com seu valor respectivo da origem
      //ClientDataSet1.Fields[c].Value := ClientDataSet1.Fields[c].Value;
      //Corrigido em 16/07/2009 15:45
      ClientDataSet1.Fields[c].Value := ADOQuery1.Fields[c].Value;
    //grava o registro na tabela destino (em memória)
    ClientDataSet1.Post;
    //confirma as alterações no banco de dados
    //(desnecessário se não for um ClientDataSet)
    ClientDataSet1.ApplyUpdates(0);
    //vai para o próximo registro da origem
    ADOQuery1.Next;
  end;
  //fecha a origem
  ADOQuery1.Close;
  //fecha o destino
  ClientDataSet1.Close;
end;

Backup com MySQL e Delphi


Mesmo que saibamos tudo sobre o MySQL Server 5.0, comandos, sintaxe, recursos entre outras coisas, tudo ficará perdido se um vírus ou outra praga digital invadir o computador e acabar com os nossos dados. Por isso é bom fazer backups da base de dados

O MySQL Server 5.0 tem um recurso chamado mysqldump, que ajuda a fazer backups da base de dados, mas, o problema é que tudo por meio de linhas de comando, o que um usuário final (na maioria dos casos) não saberá fazer.

Para contornar essa barreira, podemos utilizar os arquivos bat, automatizando o processo de backup, ou melhor, do mysqldump! Veja um exemplo:

  cd C:\Arquivos de programas\MySQL\MySQL Server 5.0\bin
  mysqldump nome_da_base_de_dados > caminho_onde_ficara_salvo_o_bakup
  -u Nome_do_usuario_do_mysql -p senha_do_mysql -x -e -a -v
  exit

Essa é a sintaxe do comando que deve conter o arquivo bat, e pronto!

Para executar o bat de uma aplicação em Delphi, use a seguinte linha de comando:

  WinExec(Pchar('Caminho onde esta salvo o arquivo bat'), SW_SHOWNORMAL);

Bom pessoal, espero que tenham gostado da dica.

Segue um link para baixar um pequeno programa que fiz para demonstrar como fazer a conexão com MySQL Server 5.0 e com o exemplo de arquivo bat para o backup: exemplo_backup_mysql.zip

Um lembrete: para compilar o exemplo, copie-o para o seu C:\