segunda-feira, 10 de setembro de 2012

Identar código no Delphi 7

Quem está começando a aprender Delphi 7 e já tem alguma familiaridade com alguma outra ferramenta de programação ou editor de textos, fora o bloco de notas, já está acostumado a identar seus códigos de forma que estes fiquem organizados para uma melhor manutenção posteriormente.

Se você é um dos que não identa, pode começar a se acostumar com esta técnica, que é praticamente exigida por alguns padrões lá fora e, como falei anteriormente, é de essencial para uma melhor manutenção e interpretação do código.

Mas o que é identar?

Dentro da computação, indentação é um termo aplicado ao código fonte de um programa para indicar que os elementos hierarquicamente dispostos têm o mesmo avanço relativamente à posição (y,0).

Na maioria das linguagens a indentação tem um papel meramente estético, tornando a leitura do código fonte muito mais fácil (read-friendly), porém é obrigatória em outras. Python, occam e Haskell, por exemplo, utilizam-se desse recurso tornando desnecessário o uso de certos identificadores de blocos ("begin" e/ou "end").

A verdadeira valia deste processo é visível em arquivos de código fonte extensos, não se fazendo sentir tanto a sua necessidade em arquivos pequenos (relativamente ao número de linhas)

Para qualquer programador, deve ser um critério a ter em conta, principalmente, por aqueles que pretendam partilhar o seu código com outros. A Indentação facilita também a modificação, seja para correção ou aprimoramento, do código fonte.

Identando no Delphi 7

Diferente dos outros editores, o Delphi 7 não permite o uso da TAB após a seleção do texto para identarmos aquele bloco, se fizermos isso, a linha selecionada é excluída!!

O comando para finalmente identar nosso código é: CTRL + SHIFT + i (para avançar o código, ou seja, mover pra a direita) e CTRL + SHIFT + u (para retroceder o código ou mover para a esquerda). Lembre-se de SELECIONAR o código antes de utililzar as teclas de atalho.

segunda-feira, 27 de agosto de 2012

Quebra textos e retorna frases do tamanho especificado


Quebra textos e cria frases do tamanho especificado, com um detalhe (não reparte as palavras) a função avalia se a palavra seguinte vai caber na frase caso contrario inclui na frase seguinte.

Fiz essa função na necessidade de atender regras de tamanho em comentarios de nota fiscal.

Function QuebraTextString(Texto : String; Largura : Integer):TStringList;
var
  Original, Quebrado : TStringList;
  i, x, esp : integer;
  frase : String;
begin
  Original := TStringList.Create;
  Quebrado := TStringList.Create;

  esp := Largura;
  sBreakApart(Texto, ' ', Original);

  frase := '';
  for i := 0 to Original.Count-1 do begin
    if Length(frase) = esp then begin
      Quebrado.Add(frase);
      frase := '';
    end;
    if( Length(frase + ' ' +Original.Strings[i]) > esp) then begin
      Quebrado.Add(frase);
      frase := '';
    end;
    frase := frase + ' '+Original.Strings[i];
    if i = Original.Count-1 then begin
      Quebrado.Add(frase);
    end;
  end;
  result:= Quebrado;
end;

Desabilitar/Habilitar componentes de um form pela sua classe.


Segue procedure que permite habilitar/desabilitar componentes de determinado form de acordo com as classes passadas como parâmetro. É possível determinar quais controles não serão afetados.

procedure EnableDisableControls(Form: TForm; ClassComponents: array of TControlClass; Exclude: array of TControl; State: Boolean);
var
  i,
  j,
  z: Integer;
begin
  for I := 0 to Form.ComponentCount -1 do
    for j := Low(ClassComponents) to High(ClassComponents) do
      if High(Exclude) > -1 then
      begin
      for z := Low(Exclude) to High(Exclude) do
        if (Form.Components[i] is ClassComponents[j]) and (Form.Components[i] <> Exclude[z]) then (Form.Components[i] as ClassComponents[j]).Enabled := State;
      end
      else
        if (Form.Components[i] is ClassComponents[j]) then (Form.Components[i] as ClassComponents[j]).Enabled := State;
end;

Exemplo de uso:

EnableDisableControls(Form1, [TEdit, TMemo, TCheckBox, TRadioButton], [CheckBox1], (not Edit2.Enabled));

Neste exemplo acima todos os edits, memos, checkboxes e radiobuttons serão desabilitados/habilitados, com exceção do checkbox1.

Pesquisa SQL de datas amarzenadas em Varchar


Olá Pessoal no meu banco de dado as datas estão gravadas em varhar, estava com dificuldades p/ manipular, em pesquisa pela net adaptei algumas coisas e deu certo.
Ai vai uma parte do codigo fonte.

procedure Tfrm_media_vendas.Label13Click(Sender: TObject);

begin
//=============== calcula total de vendas no mes de janeiro====================
frm_media_vendas.query1.Close;
frm_media_vendas.query1.sql.clear;
frm_media_vendas.query1.sql.add('select SUM(VL_TOT_ORC) from orcamentos');
frm_media_vendas.query1.sql.add ('where DT_ORC like "%01/'+(Edit2.Text)+'"');
frm_media_vendas.query1.sql.add ('ORDER by CD_ORC');
frm_media_vendas.query1.Open;
frm_media_vendas.DBGrid1.Refresh;
frm_media_vendas.Label13.Caption:=IntToStr(Query1.RecordCount);
frm_media_vendas.MaskEdit1.Text:='R$'+ floatTostr(frm_media_vendas.DBGrid1.SelectedField.AsCurrency);
//=====================fim do calculo==================================
//===================Total Orçamentos Janeiro=========================
frm_media_vendas.query1.Close;
frm_media_vendas.query1.sql.clear;
frm_media_vendas.query1.sql.add('select * from orcamentos');
frm_media_vendas.query1.sql.add ('where DT_ORC like "%01/'+(Edit2.Text)+'"');
frm_media_vendas.query1.sql.add ('ORDER by CD_ORC');
frm_media_vendas.query1.Open;
frm_media_vendas.DBGrid1.Refresh;
frm_media_vendas.Label13.Caption:=IntToStr(Query1.RecordCount);
//=========================fim da pesquisa===================
end;

terça-feira, 21 de agosto de 2012

Criando um gerador de senhas


Veja nesta dica um código simples mas bastante útil, que gera senhas aleatórias podendo conter somente numeros, somente letras ou letras e números. O autor também aborda um pouco do comando try..except. Confira!
Primeiramente, vamos ao tutorial: insira em um form um Edit, abaixo dele um RadioGroup e depois outro Edit. Nesse RadioGroup, procure pela propriedade Items no Object Inspector e adicione o seguinte:

Somente números Somente letras Letras e números

Após isso, adicione dois Buttons. No primeiro mude a propriedade Caption para "Gerar" e o segundo "Limpar". No OnClick do botao "Gerar" coloque o seguinte código:

procedure TForm1.Button1Click(Sender: TObject);
const
  letras = 'abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVXWYZ';
  numeros = '1234567890';
  letrasnumeros = letras + numeros;
var
  i: integer;
begin
  try
    Edit2.Clear;
    for i := 1 to StrToInt(Edit1.Text) do
    begin
      if RadioGroup1.ItemIndex = 0 then
        Edit2.Text := Edit2.Text + numeros[random(length(numeros)) + 1]
      else if RadioGroup1.ItemIndex = 1 then
        Edit2.Text := Edit2.Text + letras[random(length(letras)) + 1]
      else if RadioGroup1.ItemIndex = 2 then
        Edit2.Text := Edit2.Text + letrasnumeros[random(length(letrasnumeros)) + 1];
    end;
  except
    showmessage('Insira somente números no primeiro Edit');
  end;
end;
Explicando

Criamos uma variavel i, do tipo inteira, que irá receber a quantidade de caracteres que o usuário quiser para a sua senha. Por isso convertemos o valor do Edit1.Text de String para Inteiro (StrToInt) dentro do for. Criamos também três constantes, adicionando a cada uma respectivamente as letras, números ou as duas juntas.

O comando "Try" funciona da seguinte maneira: falamos para o Delphi tentar executar esse código e, caso ele não conseguir, podemos utilizar o Except para apresentar, por exemplo, algumas mensagens de erro do que pôde acontecer. No exemplo, deve ser informado no Edit1 a quantidade de caracteres da senha e, caso a pessoa coloque letras ao invés de números, a função StrToInt não conseguirá ser executada. Com o Except, conseguimos informar ao usuário este problema e tiramos a mensagem de erro que o delphi emitiria, em inglês.

No segundo botão, coloque apenas:

procedure TForm1.Button2Click(Sender: TObject);
begin
  Edit2.Clear;
end;
Após isso efetue a seguinte alteração no seu Delphi : em Tool>Options, procure por Language Execeptions e desmarque "Notify on Language Execeptions". Isto fará com que o compilador do Delphi não interrompa o programa com as mensagens do depurador e deixe a mensagem ir diretamente ao programa.

Nesse momento, compile e rode sua aplicação, informe um número no primeiro edit, selecione um método de geração e veja a senha gerada no segundo edit. É o nosso código em funcionamento!

Formatando a visualização do tamanho de um arquivo


Quando se trabalha com arquivos no Delphi pode ser necessário exibir o tamanho de um arquivo, como é feito no Explorer, onde o valor não é mostrado em bytes, mas sim de acordo com o seu tamanho atual. Para a maioria, "45.678.123 Bytes" é confuso, mas "43,56 MB" não!
A seguir, temos uma função chamada FormatByteSize, que converte um valor em bytes para uma String que representa o número expressado em Bytes, Kilobytes Megabytes ou Gigabytes, dependendo do seu tamanho:

//Formata o tamanho de um arquivo
function FormatByteSize(const bytes: Longint): string;
const
  B = 1; //byte
  KB = 1024 * B; //kilobyte
  MB = 1024 * KB; //megabyte
  GB = 1024 * MB; //gigabyte
begin
  if bytes > GB then
    result := FormatFloat('#.## GB', bytes / GB)
  else
    if bytes > MB then
      result := FormatFloat('#.## MB', bytes / MB)
    else
      if bytes > KB then
        result := FormatFloat('#.## KB', bytes / KB)
      else
        result := FormatFloat('#.## bytes', bytes) ;
end;
Para usá-la, basta fazer no evento onClick de um button, por exemplo:

procedure TForm1.Button1Click(Sender: TObject);
var
  TamanhoEmBytes: Longint;
begin
  with TFileStream.Create(
    'C:\Windows\System32\calc.exe',
    fmOpenRead or fmShareExclusive)
  do try
    TamanhoEmBytes := Size;
  finally
    Free;
  end;
 
  ShowMessage( FormatByteSize(TamanhoEmBytes) );
end;

Função para Validar a Chave da Nota Fiscal Eletrônica


function ValidarChaveNFe(const ChaveNFe: string):boolean;
const
PESO : Array[0..43] of Integer = (4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2, 9, 8, 7, 6, 5, 4, 3, 2,0); /// Aqui corrigido para o Delphi XE
var
Retorno : boolean;
aChave : Array[0..43] of Char;
Soma : Integer;
Verif : Integer;
I : Integer;
begin
Retorno := false;
try
try
if not Length(ChaveNFe) = 44 then
raise Exception.Create('');

StrPCopy(aChave,StringReplace(ChaveNFe,' ', '',[rfReplaceAll]));
Soma := 0;
for I := Low(aChave) to High(aChave) do
Soma := Soma + (StrToInt(aChave[i]) * PESO[i]);

if Soma = 0 then
raise Exception.Create('');

Soma := Soma - (11 * (Trunc(Soma / 11)));
if (Soma = 0) or (Soma = 1) then
Verif := 0
else
Verif := 11 - Soma;

Retorno := Verif = StrToInt(aChave[43]);
except
Retorno := false;
end;
finally
Result := Retorno;
end;

terça-feira, 24 de julho de 2012

Os 7 passos do gerenciamento de projetos


Analisando o mercado de trabalho na área de TI, e conversando com colegas, percebo que muitos almejam chegar ao nível de ser um gerente de projeto.

Tarefa fácil? Não, um gerente de projetos deve ser um profissional praticamente completo, conhecer várias linguagens de programação, ser ótimo em lógica, saber lidar com equipes, ou seja ser um líder, saber inglês, no mínimo em nível avançado, enfim, as qualidades são muitas.

Agora vamos lembrar que nenhum de nós nasceu gerente de projeto, concordam? Nascemos "ignorantes" e é esse o desafio da vida, evoluirmos. Esforço, dedicação e principalmente disciplina, são itens fundamentais na formação de uma pessoa. Sendo assim seguem algumas dicas importantes para quem deseja ser um gerente de projeto.

1. Escolha e adote uma metodologia
2. Comunique-se: não é só o peixe que morre pela boca!
3. Defina o escopo do projeto e detalhe as atividades
4. Conheça os envolvidos e monte seu time.
5. Desenvolva o cronograma junto com quem põe a mão na massa.
6. Monitore os riscos e seja pró-ativo.
7. Formalize o início e o encerramento do projeto.
O artigo completo, pode ser visualizado no link abaixo.
http://www.microsoft.com/brasil/msdn/tecnologias/carreira/gerencprojetos.mspx

Exemplo de Aplicação para dar um Zoom na Tela


Imaginem criar uma aplicação que possibilite "darmos" um zoom por onde o mouse passar. A idéia é passarmos o mouse em um determinado local da tela e ampliar a mesma. Com Delphi podemos fazer isso facilmente. Para demonstrarmos essa facilidade vamos criar uma aplicação exemplo, e detalharmos passo-a-passo como executar o zoom por onde o mouse passar. A imagem abaixo demonstra como deve ficar a interface gráfica da aplicação de exemplo.













Vamos ao código fonte do botão Click Here
// variaveis
var Srect,Drect,PosForme:TRect;
iWidth,iHeight,DmX,DmY:Integer;
iTmpX,iTmpY:Real;
C:TCanvas;
hDesktop: Hwnd;
Kursor:TPoint;

// Ampliar a tela se esse aplicativo não for um icone
If not IsIconic(Application.Handle) then begin

// Pega as coordenadas do mouse
GetCursorPos(Kursor);
hDesktop:= GetDesktopWindow;
// PosForm representa um retangulo com as coordenadas
// Form (image control) coordenadas
PosForme:=Rect(Form1.Left,
Form1.Top,
Form1.Left+Form1.Width,
Form1.Top+Form1.Height);

//Mostra a tela ampliada
//se o cursor do mouse sair do form
If not PtInRect(PosForme,Kursor) then begin
// O codigo abaixo para ampliar o que estiver selecionado a parte da tela que estiver selecionada
iWidth:=Image1.Width;
iHeight:=Image1.Height;
Drect:=Bounds(0,0,iWidth,iHeight);
iTmpX:=iWidth / (Slider.Position * 4);
iTmpY:=iHeight / (Slider.Position * 4);
Srect:=
Rect(Kursor.x,Kursor.y,Kursor.x,Kursor.y);
InflateRect(Srect,Round(iTmpX),Round(iTmpY));
//recebe a "alça de janela" (handle) do form
C:=TCanvas.Create;
try
C.Handle:=GetDC(GetDesktopWindow);
//Transfere a parte da imagem da tela para o TImage
Image1.Canvas.CopyRect(Drect,C,Srect);
finally
ReleaseDC(hDesktop, C.Handle);
C.Free;
end;
end;

// Garantir de processar todas as mensagens do windows
Application.ProcessMessages;
end;
É obvio que devemos aumentar a parte gráfica da aplicação para podermos visualizar melhor a parte da tela que esta sendo ampliada. Fica a dica, de mais uma funcionalidade que podemos disponibilizar em nosso sistemas.

sexta-feira, 29 de junho de 2012

Lendo e gravando arquivos de texto

Existem vários métodos em Delphi para gravar arquivos texto a partir de informações gravadas em bases de dados ou para ler arquivos texto e armazená-los em bases de dados. Esta dica apresenta um destes métodos: o uso de TextFiles.

TextFile é um tipo de dado pré-definido no Delphi e corresponde ao tipo Text do Turbo Pascal e do Object Pascal.

Inicialmente para acessar um arquivo de texto, você precisa definir uma variável tipo TextFile, no local que você achar mais apropriado, da seguinte forma:

var arq: TextFile;
Vamos precisar também de uma variável tipo string para armazenar cada linha lida do arquivo:

var linha: String;
Antes de se iniciar a leitura do arquivo, precisamos associar a variavel TextFile com um arquivo fisicamente armazenado no disco:

AssignFile ( arq, 'C:\AUTOEXEC.BAT' );
Reset ( arq );
A rotina AssignFile faz a associação enquanto Reset abre efetivamente o arquivo para leitura. AssignFile corresponde à Assign do Turbo Pascal. Em seguida é necessário fazer uma leitura ao arquivo, para isto utilizaremos a procedure ReadLn:

ReadLn ( arq, linha );
O comando acima lê apenas uma linha de cada vez, assim precisamos de um loop para efetuar várias leituras até que o arquivo acabe. Para verificar o fim do arquivo, utilizaremos a função Eof:

while not Eof ( arq ) do
Agora uma rotina quase completa para fazer a leitura de um arquivo texto. Esta rotina recebe como parâmetro o nome do arquivo que será lido:

procedure percorreArquivoTexto ( nomeDoArquivo: String );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Reset ( arq );
ReadLn ( arq, linha );
while not Eof ( arq ) do
begin
{ Processe a linha lida aqui. }
{ Para particionar a linha lida em pedaços, use a função Copy. }
ReadLn ( arq, linha );
end;
CloseFile ( arq );
end;
E também uma rotina quase completa para gravação de um arquivo texto. Esta rotina recebe como parâmetro o nome do arquivo que será gravado e uma tabela (TTable) de onde os dados serão lidos:

procedure gravaArquivoTexto ( nomeDoArquivo: String; tabela: TTable );
var arq: TextFile;
linha: String;
begin
AssignFile ( arq, nomeDoArquivo );
Rewrite ( arq );
tabela.First;
while not tabela.Eof do
begin
Write ( arq, AjustaStr ( tabela.FieldByName ( 'Nome' ).AsString, 30 ) );
Write ( arq, FormatFloat ( '00000000.00', tabela.FieldByName ( 'Salario' ).AsFloat ) );
WriteLn ( arq );
tabela.Next;
end;
CloseFile ( arq );
end;
Note nesta segunda rotina, a substituição de Reset por Rewrite logo após o AssignFile. Rewrite abre o arquivo para escrita, destruindo tudo que houver lá anteriormente .

Note também o uso de Write e WriteLn para gravar dados no arquivo texto.

Finalmente note o uso de AjustaStr e FormatFloat para garantir que campos string e numericos sejam gravados com um número fixo de caracteres. FormatFloat é uma rotina do próprio Delphi enquanto AjustaStr está definida abaixo:

function AjustaStr ( str: String; tam: Integer ): String;
begin
while Length ( str ) < tam do
str := str + ' ';
if Length ( str ) > tam then
str := Copy ( str, 1, tam );
Result := str;
end;
O uso da função AjustaStr é fundamental quando você estiver gravando arquivos texto com registros de tamanho fixo a partir de bases de dados Paradox que usualmente não preenchem campos string com espaços no final.

Nomes dos arquivos que estão sendo executados:

É comum e até relativamente fácil encontrarmos rotinas para listar todas as janelas abertas. Mas muitas vezes não é apenas o caption das janelas que queremos listar e sim o nome do arquivo executável.

Veja então uma rotina que cria uma lista de strings com esses nomes:

uses TLHelp32; // não esqueça de incluir esta unit

procedure ListProcess(List: TStrings);
   var
     ProcEntry: TProcessEntry32;
     Hnd: THandle;
     Fnd: Boolean;
begin
    List.Clear;
    Hnd := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
    if Hnd <> -1 then
    begin
       ProcEntry.dwSize := SizeOf(TProcessEntry32);
       Fnd := Process32First(Hnd, ProcEntry);
       while Fnd do
       begin
          List.Add(ProcEntry.szExeFile);
          Fnd := Process32Next(Hnd, ProcEntry);
      end;
      CloseHandle(Hnd);
    end;
end;

E para utilizar esta rotina é muito simples, veja:

procedure TForm1.Button1Click(Sender: TObject);
begin
      ListProcess(ListBox1.Items);
end;

Programar meu aplicativo para abrir arquivos a partir do Windows Explorer

Inclua na seção uses: Registry

Problema:

Criei um editor de textos no Delphi. Agora gostaria que o Windows Explorer usasse este editor para abrir arquivos com a extensão .dpg e .dan. Como fazer?

Solução:

Para fazer isto será necessária a criação de algumas chaves no Registro do Windows. O exemplo abaixo cria todas as chaves necessárias.

- Coloque um TButton e no evento OnClick dele coloque o código abaixo:

procedure TForm1.Button1Click(Sender: TObject);
var
Reg: TRegistry;
begin
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.LazyWrite := false;
{ Define o nome interno (ArquivoDaniel) e uma legenda que aparecerá no Windows Explorer (Arquivo do Daniel) }
Reg.OpenKey('ArquivoDaniel', true);
Reg.WriteString('', 'Arquivo do Daniel');
Reg.CloseKey;
{ Define o comando a ser executado quando abrir um arquivo pelo Windows Explorer (NomeDoExe %1). O símbolo %1 indica que o arquivo a ser aberto será passado como primeiro parâmetro para o aplicativo - ParamStr(1). }
Reg.OpenKey('ArquivoDaniel\shell\open\command', true);
Reg.WriteString('', ParamStr(0) + ' %1'); { NomeDoExe %1 }
Reg.CloseKey;
{ Define o ícone a ser usado no Windows Explorer:
0 - primeiro ícone do EXE
1 - segundo ícone do EXE, etc }
Reg.OpenKey('ArquivoDaniel\DefaultIcon', true);
Reg.WriteString('', ParamStr(0) + ',0'); { 0 = primeiro ícone }
Reg.CloseKey;
{ Define as extensões de arquivos que serão abertos pelo meu aplicativo }
{ *.dpg }
Reg.OpenKey('.dpg', true);
Reg.WriteString('', 'ArquivoDaniel');
Reg.CloseKey;
{ *.dan }
Reg.OpenKey('.dan', true);
Reg.WriteString('', 'ArquivoDaniel');
Reg.CloseKey;
finally
Reg.Free;
end;
end;
- Coloque um TMemo;

- No evento OnShow do Form coloque o código abaixo:

procedure TForm1.FormShow(Sender: TObject);
begin
{ Se o primeiro parâmetro for um nome de arquivo existente... }
if FileExists(ParamStr(1)) then
{ Carrega o conteúdo do arquivo no memo }
Memo1.Lines.LoadFromFile(ParamStr(1));
end;
*** Para testar ***

- Execute este programa;

- Clique no botão para criar as chaves no Registro do Windows;

- Feche o programa;

- Crie alguns arquivos com as extensões .dpg e .dan;

- Vá ao Windows Explorer e procure pelos arquivos criados;

- Experimente dar um duplo-clique sobre qualquer dos arquivos com uma das extensões acima.

Observações

Existem outros recursos que poderão ser configurados. Porém, para começar, este já é um bom exemplo.

domingo, 24 de junho de 2012

Obter a quantidade de registros total e visível de uma tabela

Inclua na seção uses: DbiProcs

Os componentes TTable e TQuery possuem a propriedade RecordCount que indicam a quantidade de registros da tabela.

No entanto esta propriedade é dependente de filtros, ou seja, se tivermos uma tabela com dez registros com campo "Codigo" de 1 a 10 e aplicarmos o filtro mostrado a seguir, a propriedade RecordCount retornará 5 e não 10.

Table1.Filter := 'Codigo <= 5';
Table1.Filtered := true;
Se quizermos obter a quantidade total de registros, independentemente de filtros, devemos usar uma API do BDE conforme abaixo:

var
Total: integer;
begin
Check(DbiGetRecordCount(Table1.Handle, Total));
ShowMessage('Total de registros: ' + IntToStr(Total));
end;

Observações


Para testar o exemplo acima, o Table1 precisa estar aberto.

Os limites do InterBase

Questões / Problemas / Resumo:

Na hora de se construir uma Base de Dados, temos que ter bastante atenção quanto as limitações do Sistema Gerenciador de Banco de Dados, se não levarmos em conta, poderemos ter varias surpresas desagraveis durante o desenvolvimento da mesma....

Descrição:
Os limites do InterBase

Traduzido por: Marcos Ribeiro

Por: Iván Pons

Na hora de se construir uma Base de Dados, temos que ter bastante atenção quanto as limitações do Sistema Gerenciador de Banco de Dados, se não levarmos em conta, poderemos ter varias surpresas desagraveis durante o desenvolvimento da mesma.

Muitas vezes podemos “ignorar” o problema, e buscarmos uma solução que nos permite sair do passo como está, porém em outros casos, nós nos encontramos com uma triste realidade de um Sistema, que não tem toda a potencia de que precisamos.

Por tudo isso, e a pesar de divulgar muitas vezes o InterBase como um sistema “maravilhoso”, devemos conhecer de antemão, até onde ele pode chegar:

1 - Número máximo de clientes conectados em um servidor

Não tem um número máximo de clientes que um Servidor do IB pode servir. Dependerá de uma combinação de fatores, incluindo capacidade do Sistema Operacional, Limitações de Hardware e o que cada cliente pode no servidor. Em uma aplicação “normal”, que executa interações humanas e um servidor médio, o IB pode responder tranqüilamente a mais de 150 clientes.

2 - Tamanho Máximo da Base de Dados

O tamanho máximo direcionado de um arquivo, em um único arquivo é de 2Gb no Windows95/98, 4Gb em NT4 e na maioria dos sistemas UNIX. As limitações dependem do Sistema Operacional. Em uma configuração de múltiplos arquivos, podem chegar a ter o tamanho de Terrabytes.

3 – Máximo número de arquivos por Base de Dados

Pode ser, 2 elevado a 16 (65.536), porque os arquivos estão numerados com um número de 16 bits. Os arquivos Shadow apontam para este limite. É o limite do InterBase, porém a maioria dos sistemas operacionais tem um limite menor de arquivos que podem ser usados simultaneamente por um único processo.

4 - Número Máximo de Tabelas em uma Base de Dados

Podem ser, 2 elevado a 16 (65.536), porque as tabelas estão enumeradas usando um número de 16 bits.

5 – Tamanho Máximo de Filas

64Kb. Os Blobs e Arrays contribuem cada um com 8Bytes. As tabelas de sistemas tem uma limitação de tamanho de coluna de 128 Kb.

6 – Número Máximo de Filas e Colunas por tabela

Pode ser, 2 elevado a 32 filas, e as filas estão numeradas com um inteiro de 32 bits, por tabela. O número de colunas em uma fila dependerá do tipo de dados usado. Assim, uma fila pode ter um tamanho de 64K, e poderíamos definir 16.384 colunas do tipo INTEGER (quatro bytes) em uma tabela.

7 – Número Máximo de Índices por tabela

Pode ser 2 elevado a 16 (65.356), porque estão enumerados com um inteiro de 16 bits.

8 – Número Máximo de Índices por Base de Dados

Pode ser 2 elevado a 32, porque se podem criar 216 tabelas por Base de Dados, e cada tabela pode chegar a ter 216 índices.

9 – Tamanho Máximo da Chaves de um Índice

Inicia com 256 bytes para uma chave simples de coluna, aumentando-se 200 para chaves de múltiplas colunas, restando 4 bytes por cada coluna adicional.

10 – Máximo número de eventos por Procedimento Armazenado

Não tem restrições para desenvolvimento, porém tem um limite prático, dado por um limite em tamanho do código de um Procedimento Armazenado em uma Trigger.

11 – Tamanho máximo do código de um Procedimento Armazenado em uma Trigger

48Kb de BLR (Linguagem compilada de um Procedimento Armazenado ou de uma Trigger.)

12 – Tamanho Máximo de um Blob

O tamanho máximo de um Blob dependerá do tamanho de página de uma Base de Dados. Assim:

1Kb de tamanho de página à 64Mb

2Kb de tamanho de página a 512Mb

4Kb de tamanho de página a 4Gb

8Kb de tamanho de página a 32 Gb

O tamanho máximo de um segmento de um Blob é de 64Kb.

13 – Número máximo de tabelas em um Join

Não tem restrições, porém o tempo de resposta em uma tarefa de cruzar tabelas e exponencial em relação com o número de tabelas que participam em um JOINEI número máximo de tabelas em um JOIN, para que seja eficiente é sobre 16 tabelas, porém a realidade e experiência com nossas aplicações, com uma carga real de dados em nossas tabelas poderá ter um rendimento aceitável.

14 – Número máximo de consultas dentro de outras consultas

Não tem restrições, porém o limite prático dependerá do tipo de consulta de teremos.

15 – Número máximo de colunas para um índice composto

16

16 – Número de Procedimentos Armazenados na Trigger dentro de um PA em uma Trigger.

Em Windows 95/98/NT 750. Em plataformas Unix 1000.

17 – Tamanho máximo de chave em uma sentença SORT

32Kb

18 – Entre Datas