quarta-feira, 2 de fevereiro de 2011

Gaste tempo e depois ganhe mais ainda ao ler este artigo


Algumas idéias citadas abaixo ajudarão profissionais que trabalham com banco de dados a serem mais produtivos e atingir metas firmadas no acordo de nível de serviços (SLAs)
Não paramos e não podemos parar, desde o momento em que acordamos até a hora de se deitar. O mundo está cada vez mais competitivo, lutando por sobrevivência, e podemos afirmar que certamente neste momento há alguém estudando e aprendendo novas tecnologias ou tentando inventar um novo “Google”, por exemplo. Ninguém tem tempo a perder, ao ler este artigo você está gastando ele, mas espero que após a leitura lhe ajude a ganhar outros tantos que lhe dará tempo e uma vida mais calma.

A rotina de quem trabalha com dados é incessante, a infinidade de lugares, formatos e tamanhos, no qual é obrigado a controlar para manter simples conjuntos de bytes em algo compreensível é importante, faz com que se gaste muito tempo criando e executando rotinas estressantes que exigem muita habilidade e conhecimentos técnicos.


Hoje em dia os Databases Administrators(DBAs) são obrigados a gerenciar ambientes complexos que podem envolver diferentes plataformas de banco de dados, nas quais dependem de uma série de tarefas e rotinas, que precisam ser aprendidas em horas e dominadas em dias para serem aplicadas em todas as instâncias. Além disso tem a necessidade de aprender a utilizar a ferramenta de gestão de cada fabricante, que aplicam conceitos diferentes e tornam o aprendizado ainda mais demorado.


Uma forma de resolver estes problemas e também é uma dica que ofereço, é escolher uma ferramenta que permita gerenciar de maneira igual diferentes tipos de banco de dados, permitindo que o DBA domine uma única ferramenta e o seu aprendizado já seja inserido e replicado em qualquer plataforma de banco de dados, direcionando a preocupação do DBA em resolver o problema rápido, sem intervenção das peculiaridades de uma plataforma.


Ao pensarmos em modelagem, muitos a utilizam na fase de criação da estrutura do banco de dados e após a produção da aplicação abandonam o modelo, deixando obsoleto e sem manutenção. Desta maneira começam a surgir as famosas “gambiarras” para manter o sistema em funcionamento, mas de forma “sofrível”.


A modelagem não deve ser apenas utilizada na fase de criação da aplicação, ao integrar a ferramenta de modelagem no banco de dados, possibilitará ainda controle de todo o ciclo de vida e das mudanças, que forem realizadas e propagadas de maneira mais rápida, contribuindo também para uma documentação atualizada e sempre disponível de forma automática.


Outro conselho é escolher uma ferramenta de modelagem que propicie a empresa trabalhar de forma articulada e centralizada, permitindo que analistas de negócios façam o levantamento de requisitos e necessidades de seus usuários, reduzindo o mal entendimento e possibilitando que áreas especialistas em captação de informação possam trabalhar de maneira integrada e automatizada com DBAs e arquitetos de dados. Isso tudo porque ao realizar o modelo conceitual que foi gerado a partir de uma necessidade de negócio será permitido a geração do modelo do banco de dados lógico e físico já direcionado ao usuário, evitando desperdício de esforço aplicado em retrabalho.


Ao termos um modelo atualizado e em uso podemos, ir mais além e, oferecer aos desenvolvedores acesso ao dicionário de dados padronizado seguindo templates pré-fabricados para serem reutilizados pelos desenvolvedores, evitando que eles “reinventem a roda”. Ao sugerir e criar alternativas ou até mesmo novos objetos para armazenar dados, o desenvolvimento de software tem conseguido ser satisfatório seguindo implementações como Gang of Four (GoF) e UML patterns ,do mesmo modo a construção de um banco de dados não precisa ser feito de maneira diferente.


Arquitetos podem disponibilizar para os desenvolvedores estruturas e associações que necessitarão ser reutilizadas com frequência como dados cadastrais de clientes ou produtos, indicando os campos obrigatórios e tipos de dados utilizados, o ganho de tempo estará na constante reutilização e na transformação dos dados para serem movidos ou carregados via ETL.


Boas práticas de mercado são ótimas para serem lidas, nos ajudam a entender como o mercado trabalha e para onde estamos caminhando. Entretanto sabemos que muitas vezes a cultura e até mesmo a dificuldade em adotar uma ou outra técnica acabam dependendo de diversos fatores, mas ao mesmo tempo em que você ou sua empresa não adota ou não se adapta ao mundo de hoje, serão obrigados a viver o mundo de ontem, no qual a tecnologia e seus concorrentes não fazem questão de lembrar.

Função FormatDateTime


FormatDateTime é uma função que retorna uma string de acordo com o formato passado como 1º parametro, tendo como base o 2º parametro que é a data. Veja nesta dica todos os detalhes e exemplos de uso desta função
Ela está presente na unit SysUtils (Delphi 7), com a seguinte implementação:
function FormatDateTime(const Format: string; DateTime: TDateTime): string;
begin 
  DateTimeToString(Result, Format, DateTime); 
end;
Segue um exemplo de uso, para ser colocado no evento onClick de um button, por exemplo:
begin 
  ShowMessage(FormatDateTime('dd/mm/yyyy', (Now + 1))); 
end;
Se hoje for 17/12/2010, este código resultará em uma mensagem contendo:
‘18/12/2010'.
Uma das grandes facilidade que a função nos traz é durante a interação com um banco de dados. Exemplo para o mySQL:

begin 
  MyQuery.SQL.Text := Format( 
    'SELECT * FROM `log` WHERE `date` BETWEEN ''%s'' AND ''%s''', 
    [ 
      // Data inicial 
      FormatDateTime('yyyy-mm-dd', (Now)),
      // Data final 
      FormatDateTime('yyyy-mm-dd', (Now + 1)) 
    ]); 
end;
Veja agora a tabela com os formatos possíveis e seus respectivos resultados, considerando a data e hora "02/09/2008 07:04:01":
Sintaxe Finalidade Resultado
FormatDateTime('c', Now) Resulta na Data e hora com o formato ShortDateFormat + LongTimeFormat. (Se for exatamente meia-noite não irá mostrar a hora) 02/09/2008 07:04:01
FormatDateTime('d', Now) Resulta no valor número que representa o Dia do mês ( sem 0 na frente ) 2
FormatDateTime('dd', Now) Resulta no valor número que representa o Dia do mês ( com 0 na frente [00] ) 02
FormatDateTime('ddd', Now) Resulta na abraviação do nome do dia da semana ter
FormatDateTime('dddd', Now) Resulta no nome do dia da semana terça-feira
FormatDateTime('ddddd', Now) Resulta na data formatada usando ShortDateFormat 02/09/2008
FormatDateTime('dddddd', Now) Resulta na data formatada usando LongDateFormat terça-feira, 2 de setembro de 2008
FormatDateTime('m', Now) Resulta no valor número que representa o mês ( sem 0 na frente ) 9
FormatDateTime('mm', Now) Resulta no valor número que representa o mês ( com 0 na frente [00] ) 09
FormatDateTime('mmm', Now) Resulta na abreviação do nome do mês set
FormatDateTime('mmm', Now) Resulta no nome do mês setembro
FormatDateTime('y', Now) Resulta no ano em dois digitos 08
FormatDateTime('yyyy', Now) Resulta no ano em quatro digitos 2008
FormatDateTime('h', Now) Resulta nas horas ( sem 0 na frente ) 7
FormatDateTime('hh', Now) Resulta nas horas ( com 0 na frente [00] ) 07
FormatDateTime('n', Now) Resulta nos minutos ( sem 0 na frente ) 4
FormatDateTime('nn', Now) Resulta nos minutos ( com 0 na frente [00] ) 04
FormatDateTime('s', Now) Resulta nos segundos ( sem 0 na frente ) 1
FormatDateTime('ss', Now) Resulta nos segundos ( com 0 na frente [00] ) 01
FormatDateTime('z', Now) Resulta nos milisegundos ( sem 0 na frente ) 31
FormatDateTime('zzz', Now) Resulta nos milisegundos ( com 0 na frente [000] ) 031
FormatDateTime('t', Now) Resulta na hora formatada usando ShortTimeFormat 07:04
FormatDateTime('tt', Now) Resulta na hora formatada usando LongTimeFormat 07:04:01
FormatDateTime('am/pm', Now) Reajusta a hora resultada para horários de 12 horas (manha e tarde)



segunda-feira, 31 de janeiro de 2011

Programa - Simulação de Lucro Com Rendimento Mensal


Galera Delphiana! Bom, esta dica que escrevo é muito simples e se trata de um simulador de rendimento de aplicação financeira mensalmente.
O arquivo do projeto encontra-se compactado e disponivel para download aqui (7,64 KB).
Dentro dele, estão todos os códigos desenvolvidos, que não são nada complexos.

Apagando itens selecionados de um ListBox

 
Esta dica mostra como apagar vários itens de uma só vez de um ListBox, não importando se eles são selecionados em sequência ou aleatoriamente. Lembrando que para selecionarmos vários itens de um ListBox, sua propriedade MultiSelect deve estar ativada. Segue o código:
//A procedure tem que ser declarada na sessão "Public" ou "Private" da unit
procedure TForm1.ApagaVarios (var ListBox: TListBox);
var
  i: integer;
  lista: TStringList;
begin
  for i:=0 to ListBox.Items.Count-1 do
    if ListBox.Selected[i] then
      ListBox.Items[i] := '';

  lista:= TStringList.Create;
         
  for i:=0 to ListBox.Items.Count-1 do
    if ListBox.Items[i] <> '' then
      lista.Add(ListBox.Items[i]);

  Listbox.Clear;
  ListBox.Items.Assign(lista);  
  lista.Free;
end;
Para usá-la, coloque um componente ListBox e um componente Button em seu form. Adicione alguns itens no ListBox e ative a sua propriedade MultiSelect, conforme comentado no início e, no onClick do botão, faça o código que chama a procedure para apagar os itens selecionados:

procedure TForm1.Button1Click(Sender: TObject);
begin
  ApagaVarios(ListBox1);
end;
Por: David
Contato: sapodiou2@bol.com.br



Dica do editor

Segue abaixo uma outra forma de se fazer o mesmo procedimento, de maneira mais otimizada:

procedure TForm1.ApagaVarios2(var ListBox: TListBox);
var
  i: integer;
begin
  i := 0;
  while i <= ListBox.Items.Count-1 do
  begin
    if ListBox.Selected[i] then
      ListBox.Items.Delete(i)
    else
      i := i + 1;
  end;
end;

sexta-feira, 28 de janeiro de 2011

Abreviar Nomes


Algumas vezes precisamos transformar, via programação, um nome como "Fulano Beltrano Ciclano" em "Fulano B. Ciclano". Veja nesta dica uma função para abreviar nomes completos e resolver casos como este.
Observação: É importante lembrar que o código ASCII #32 representa o caracter "espaço".

function AbreviarNome(Nome: String): String;
var
  Nomes: array[1..20] of string;
  i, TotalNomes: Integer;
begin
  Nome := Trim(Nome);
  Result := Nome;
  Nome := Nome + #32;
  i := Pos(#32, Nome);
  if i > 0 then
  begin
    TotalNomes := 0;
    while i > 0 do
    begin
      Inc(TotalNomes);
      Nomes[TotalNomes] := Copy(Nome, 1, i - 1);
      Delete(Nome, 1, i);
      i := Pos(#32, Nome);
    end;

    if TotalNomes > 2 then
    begin
      for i := 2 to TotalNomes - 1 do
        if Length(Nomes[i]) > 3 then
          Nomes[i] := Nomes[i][1] + '.';

      Result := '';
      for i := 1 to TotalNomes do
        Result := Result + Trim(Nomes[i]) + #32;

      Result := Trim(Result);
    end;
  end;
end;
Para testá-la, coloque em um form dois edits e um button, fazendo no onClick do button:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit2.Text := AbreviarNome(Edit1.Text);
end;

terça-feira, 25 de janeiro de 2011

Criando componente de data para Banco de Dados


Como percebemos em muitos fóruns, várias pessoas buscam componentes de data para Banco de Dados. Nesta matéria você vai aprender a criar o seu próprio componente para acesso a datas com banco de dados
Se você só desejar pegar o componente, segue abaixo a Unit correspondente ao Componente, que é derivado de TDateTimePicker. Mas se quer aprender e mais detalhes, logo mais abaixo terá as explicações.
unit DBDateTimePicker;

interface

uses
SysUtils, Classes, Controls, ComCtrls, Forms, Dialogs, Graphics, DBCtrls,DB, stdctrls; 

type
TDBDateTimePicker = class(TDateTimePicker)
private
  { Private declarations }
  FDataLink : TFieldDataLink;
  function GetDataField:String;
  procedure SetDataField(const Value : string);
  function GetDataSource:TDataSource;
  procedure SetDataSource(const Value : TDataSource);
  procedure DataChange(Sender:TObject);
  procedure UpdateData(Sender:TObject);
  procedure Change;override;
protected
  { Protected declarations }
public
  { Public declarations }
  constructor Create(AOwner:TComponent);override;
  destructor Destroy;override;
  property Field: TField read GetField;
published
  { Published declarations }
  property DataSource : TDataSource read GetDataSource Write SetDataSource;
  property DataField : String read GetDataField write SetDataField;
end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents("Fernando", [TDBDateTimePicker]);
end;

{ TDBDateTimePicker }

procedure TDBDateTimePicker.Change;
begin
  FDataLink.Modified;
  inherited Change;
  Try
    FDataLink.Edit;
    FDataLink.UpdateRecord;
  Except
  End;
end;

constructor TDBDateTimePicker.Create(AOwner: TComponent);
begin
  inherited;
  FDataLink := TFieldDataLink.Create;
  FDataLink.OnDataChange := DataChange;
  FDataLink.OnUpdateData := UpdateData;
  FDataLink.Control := self;
  Width := 100;
end;

procedure TDBDateTimePicker.DataChange(Sender: TObject);
begin
  Date := FDataLink.Field.AsDateTime;
end;

destructor TDBDateTimePicker.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

function TDBDateTimePicker.GetDataField: String;
begin
  Result := FDataLink.FieldName;
end;

function TDBDateTimePicker.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBDateTimePicker.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

procedure TDBDateTimePicker.SetDataSource(const Value: TDataSource);
begin
  FDataLink.DataSource := Value;
end;

procedure TDBDateTimePicker.UpdateData(Sender: TObject);
begin
  FDataLink.Field.AsDateTime := FDataLink.Field.AsDateTime;
end;

end.

Detalhes:
Quem já conhece o desenvolvimento de componentes para Banco de Dados, pode achar que basta criar as propriedades comuns em banco de dados:

DataSource - Que identifica o objeto da classe TDataSource ao qual o componente está vinculado.
DataField - O nome do campo da tabela cujo valor do registro corrente será exibido e/ou editado pelo componente. 
Porém, como a Borland é maravilhosa, ela desenvolveu uma nova classe chamada TFieldDataLink, será desta que criaremos um componente para acessos a Dados. Esta classe possui duas propriedades principais:

DataSource - Que identificará o componente da classe TDataSource ao qual o nosso componente será vinculado.
FieldName - Que indentificará o nome do campo ao qual o nosso componente será vinculado.

Agora, ao invés de criarmos campos internos, basta usar as propriedades da classe TFieldDataLink (que precisa ser criado e destruído por nosso Componente).

Antes de começarmos, precisamos declarar certas Units:

dbctrls - onde se encotra a classe TFieldDataLink.
db - onde se encontra a classe TDataSource.
uses SysUtils, Classes, Controls, ComCtrls, Forms, Dialogs, Graphics, DBCtrls,DB, stdctrls;
Vamos lá.. 

Precisaremos então criar um objeto interno do tipo TFieldDataLink.

Na sessão private:
FDataLink : TFieldDataLink;
Agora precisamos definir o método de leitura e de escrita dos campos DataSource e DataField. Normalmente, Get Leitura, Set escrita.
-----DataSource
function GetDataSource : TDataSource;
procedure SetDataSource(Value : TDataSource);
-----DataField
function GetDataField : string;
procedure SetDataField(Value : string);
Vamos declarar as propriedades que aparecerão no Object Inspector. Na área Published declarar:
property DataSource : TDataSource read GetDataSource write SetDataSource;
property DataField : string read GetDataField write SetDataField;

Iremos agora implementar esses métodos pressionando CTRL+SHIFT+C
function TDBDateTimePicker.GetDataSource: TDataSource;
begin
  Result := FDataLink.DataSource;
end;

procedure TDBDateTimePicker.SetDataSource(const Value: TDataSource);
begin
  FDataLink.DataSource := Value;
end;

function TDBDateTimePicker.GetDataField: String;
begin
  Result := FDataLink.FieldName;
end;

procedure TDBDateTimePicker.SetDataField(const Value: string);
begin
  FDataLink.FieldName := Value;
end;

Vamos definir o método de "Construção" e de "Destruição". Faremos assim, dentro de public:
destructor Destroy;override;
constructor Create(Aowner : TComponent);override;

Pressionando Novamente CTRL+SHIFT+C

Implementaremos esses métodos assim:
constructor TDBDateTimePicker.Create(AOwner: TComponent);
begin
  inherited;
  FDataLink := TFieldDataLink.Create;
end;

destructor TDBDateTimePicker.Destroy;
begin
  FDataLink.Free;
  inherited;
end;

Aparentemente nosso componente está funcionando. Mas somente se você desejar EXIBIR os dados. Se alterado o seu conteúdo, ele não sofrerá modificações, pois não há nenhum método para identificar esta modificação. Então vamos lá.

Na classe TFieldDataLink tem o evento OnDataChange, que é executado sempre que o valor armazenado for modificado.

Na área private:
procedure DataChange(Sender : TObject);
Implementamos com CTRL+SHIFT+C e completaremos da seguinte forma:
procedure TDBDateTimePicker.DataChange(Sender: TObject);
begin
  Date := FDataLink.Field.AsDateTime;
end;

Precisamor associá-lo ao evento OnDataChange de FDataLink, faremo isso no Create da seguinte forma:
FDataLink.OnDataChange := DataChange
Agora precisaremos criar um componente para refletir alterações feitas pelo próprio componente. O procedimento responsável por isso é o OnUpdateData do FDataLink, novamente na área Private:
procedure UpdateData(Sender : TObject).
Implementamos com CTRL+SHIFT+C e completaremos da seguinte forma:
procedure TDBDateTimePicker.UpdateData(Sender: TObject);
begin
  FDataLink.Field.AsDateTime := FDataLink.Field.AsDateTime;
end;

Precisamos associá-lo ao evento OnUpdateData de FDataLink. Faremos isso no Create da seguinte forma:
FDataLink.OnUpdateData := UpdateData;
Precisaremos ainda, criar o método change da classe-base de maneira que o valor armazenado no campo seja alterado sempre que o usuário alterar o texto exibido pelo componente

Na área private:
procedure Change;override;

Implementamos...

procedure TDBDateTimePicker.Change;
begin
  FDataLink.Modified;
  inherited Change;
  Try
    FDataLink.Edit;
    FDataLink.UpdateRecord;
  Except
  End;
end;

Stored Procedures, Triggers e Views


Conheça neste pequeno artigo os principais objetos de um SGBD, tendo em vista que o uso correto destes melhora a velocidade do banco, facilitando até a garantia da integridade entre as tabelas, sem que o programa precise se preocupar com isto

Stored Procedures (SPs) – Procedimentos Armazenados: são equivalentes às subrotinas da linguagem normal. Nelas podem ser inclusas estruturas de repetição e de decisão, executa cálculos, inserções e updates dentro do banco, além de poder ou não retornar datasets (conjunto de dados). Pode ser usado para confecção de relatórios que possuem vários parâmetros ou em rotinas que efetuam vários cálculos. A principal vantagem está na diminuição do tráfego pela rede, quando um comando SQL é mandado pela rede, será mandada toda a consulta e, no caso das SPs seria enviado pela rede apenas os parâmetros, além disso o motor do FB analisa se a expressão está OK, isto ocorre a cada requisição do comando SQL, já no uso de SPs sua otimização é feita no momento da criação, não precisando passar por um interpretador a cada requisição ao banco, ganhando muito em performance com relação às querys convencionais.

Triggers – Gatilhos: diferentemente das SPs as triggers não retornam datasets, porém tem uma característica muito importante: elas são acionadas automaticamente pela alteração da tabela à qual está vinculada. Qual a vantagem disto? As triggers podem ser utilizadas para garantir a integridade dos dados. Imagine que temos a tabela funcionários e a tabela histórico de salário, ao atualizar o salário de um funcionário temos que inserir os dados anteriores na tabela de histórico de salários. Com o uso de triggers isto acontece automaticamente sem que a aplicação precise se preocupar com isto.

Views – Visões: São úteis qando há realização de várias tabelas na mesma consulta. Uma view não é nada mais do que um “select” armazenado no banco, só que tem a vantagem de já estar otimizada, tendo as mesmas características das SPs neste quesito. No uso de views temos consultas com menor tempo de resposta, fazendo com que o Sistema fique mais leve.

Curso de Delphi: 7.Consultas SQL