Fórum gerar código automáticamente #293901

31/08/2005

0

Salve galera!
tenho aqui um procedure pra gerar código automaticamente... só que ele é limitado, pois ele gera um numero a partir do ultimo registro(table.last) da minha tabela. E se der um problema e o ultimo numero gerado pelo sistema for parar no meio da tabela? o sistema vai gerar um erro de violação de PrimaryKey... (esse erro está acontecendo comigo...)

Alguem teria um jeito melhor ai que pudesse varrer a tabela em busca do maior numero contido no campo ´código´ para que nao desse mais esse erro....

Segue abaixo o código atual:
----------------------------------
procedure TAutores.Btn_NovoClick(Sender: TObject);
var
Cod1 : Integer;
Cod2 : Integer;
begin
    Limpa_Edit;
    Edit_enable;

    // Contador de codigo
    
    DM.Tbl_Autores.Last;
    Cod1 := DM.Tbl_AutoresCodigo.AsInteger;
    Cod2 := Cod1 + 1;
    Edit_Codigo.Text := IntToStr(Cod2);

    //--------------------------------------
end;



tabela
-------
CREATE TABLE AUTORES (

    CODIGOINTEGER NOT NULL,
    AUTOR       VARCHAR(90) NOT NULL,
    
    CONSTRAINT PK_AUTORES PRIMARY KEY (CODIGO)
);



Mahdak

Mahdak

Responder

Posts

31/08/2005

Rjun

Faça um select que retorno o maior valor do campo código.

SELECT MAX(Codigo) FROM Autores



Responder

Gostei + 0

31/08/2005

Mahdak

Faça um select que retorno o maior valor do campo código.
SELECT MAX(Codigo) FROM Autores


Rjun, fiz o seguinte com a sua dica, mas nao deu certo nao. ele só funcionou para adicionar o primeiro registro, mas para o segundo em diante nao deu... simplesmente ele continua colocando o código 1...


DM.Tbl_Autores.SelectSQL.Clear;
    cod := DM.Tbl_Autores.SelectSQL.add(´SELECT MAX(Codigo) FROM Autores´);
    Edit_Codigo.Text := IntToStr(Cod+1);




o que faço????


Responder

Gostei + 0

31/08/2005

Rjun

Não entendi muito bem o que você fez. Usa Query em vez de Table.

DM.qryProximoCodigo.SQL.Clear;
DM.qryProximoCodigo.SQL.add(´SELECT :NovoCodigo = MAX(Codigo) + 1 FROM Autores´); 
DM.qryProximoCodigo.Open;
try
  Edit_Codigo.Text := DM.qryProximoCodigo.ParamByName(´NovoCodigo´).AsString;
finally
  DM.qryProximoCodigo.Close;
end;



Responder

Gostei + 0

31/08/2005

Michelli88

Nao deu certo porque isso:

cod := DM.Tbl_Autores.SelectSQL.add(´SELECT MAX(Codigo) FROM Autores´);

Vai retornar quantos registros foram alterados, e nao o codigo!

faz assim:
Query.SelectSQL.add(´SELECT MAX(Codigo) as ultimoCodigo FROM Autores´);

cod := Query.fieldbyname(´ultimoCodigo´).AsInteger;

;-)


Responder

Gostei + 0

31/08/2005

Gandalf.nho

Qual é o banco de dados?


Responder

Gostei + 0

31/08/2005

Mahdak

Não entendi muito bem o que você fez. Usa Query em vez de Table.
DM.qryProximoCodigo.SQL.Clear;
DM.qryProximoCodigo.SQL.add(´SELECT :NovoCodigo = MAX(Codigo) + 1 FROM Autores´); 
DM.qryProximoCodigo.Open;
try
  Edit_Codigo.Text := DM.qryProximoCodigo.ParamByName(´NovoCodigo´).AsString;
finally
  DM.qryProximoCodigo.Close;
end;


- Seguinte, o Banco de dados é FireBird 1.5 extensão .FDB
Rjun, esse seu código retornou o seguinte erro:

´SQL error, line1, char 10 = ´, ou seja algum problema com o sinal de igualdade?


// Contador de Código
    DM.qry_autores.SelectSQL.Clear;
    DM.qry_autores.SelectSQL.add(´SELECT :NovoCodigo = MAX(Codigo) + 1 FROM Autores´);
    DM.qry_autores.Open;
    try
      Edit_Codigo.Text := DM.qry_autores.ParamByName(´NovoCodigo´).AsString;
    finally
      DM.qry_autores.Close;
    end;



Responder

Gostei + 0

31/08/2005

Motta

Faça um select que retorno o maior valor do campo código.
SELECT MAX(Codigo) FROM Autores



SELECT (MAX(CODIGO) + 1 ) PROX
FROM TABELA

EXISTINDO VALOR !!


Responder

Gostei + 0

31/08/2005

Mahdak

[quote:16881a8d7e=´Rjun´]Faça um select que retorno o maior valor do campo código.
SELECT MAX(Codigo) FROM Autores



SELECT (MAX(CODIGO) + 1 ) PROX
FROM TABELA

EXISTINDO VALOR !![/quote:16881a8d7e]

coloquei o primeiro registro no banco manualmente e ele nao gerou o codigo 2... nao funcionou nao...

// Contador de Código
    DM.qry_autores.Open;
    DM.qry_autores.SelectSQL.Clear;
    COD := DM.qry_autores.SelectSQL.add(´SELECT (MAX(CODIGO) + 1 ) PROX FROM AUTORES ´);
    DM.qry_autores.Close;


    Edit_Codigo.Text := IntToStr(cod);



Responder

Gostei + 0

31/08/2005

Motta

// Contador de Código
DM.qry_autores.Open;
DM.qry_autores.SelectSQL.Clear;
DM.qry_autores.SQL.add(´SELECT (MAX(CODIGO) + 1 ) PROX FROM AUTORES ´);
dm.qry_autores.open;
cod := dm.qry_autores.fields[0].AsInteger;
DM.qry_autores.Close;


Edit_Codigo.Text := IntToStr(cod);


Responder

Gostei + 0

31/08/2005

Gandalf.nho

Se seu banco é Firebird, pq não usa generator?


Responder

Gostei + 0

31/08/2005

Mahdak

// Contador de Código DM.qry_autores.Open; DM.qry_autores.SelectSQL.Clear; DM.qry_autores.SQL.add(´SELECT (MAX(CODIGO) + 1 ) PROX FROM AUTORES ´); dm.qry_autores.open; cod := dm.qry_autores.fields[0].AsInteger; DM.qry_autores.Close; Edit_Codigo.Text := IntToStr(cod);



Motta, deu certo, porem sómente quando ja tenho um valor inicial, por que quando a tabela esta vazia esse codigo retorna NULL e nao envia o numero 1 para o primeiro registro da tabela quando vou inserir o mesmo...


Responder

Gostei + 0

31/08/2005

Mahdak

Se seu banco é Firebird, pq não usa generator?


Gandalf, voce poderia me dar um exemplo de Generator? ouvi falar que é muito bom....

Abraços!


Responder

Gostei + 0

31/08/2005

Mahdak

[quote:7b8460153d=´gandalf.nho´]Se seu banco é Firebird, pq não usa generator?


Gandalf, voce poderia me dar um exemplo de Generator? ouvi falar que é muito bom....

Abraços![/quote:7b8460153d]


nesse curto espaço de tempo consegui atravez das pesquisas aqui no clube que posso criar o generator automaticamente pelo IBExpress, e depois linkar ele com o meu IBDataSet.. até ai ja consegui, mas agora eu tenho um botão ´novo´ em minha aplicação onde ele pega o numero a ser gerado no meu GenId e coloca em um edit pra eu ver... que codigo eu teria que uso pra fazer isso funcionar???
veja se esse raciocinio está correto:
DM.qry_autcod.Close;
    DM.qry_autores.SelectSQL.Clear;
    cod := DM.qry_autores.SelectSQL.add(´select gen_id(GEN_AUTORES_ID, 1) from rdb$database´);
    DM.qry_autores.Open;


    Edit_Codigo.Text := IntToStr(cod);




Responder

Gostei + 0

01/09/2005

Michelli88

La no IBDataset, tem a propriedade GeneratorField voce vai ter ligar o GenId e o campo que vai receber os codigos gerados!


Responder

Gostei + 0

01/09/2005

Mahdak

Pessoal, nao gostei muito do GenID, por que ele incrementa o codigo, e nao decrementa caso eu cancele a operação... seria perigoso em um sistema multi usuarios criar uma rotina de decrementação do código... entao resolvi juntar as ideias lá do clube... resolvi ficar com essa:

procedure TAutores.Btn_NovoClick(Sender: TObject);
var
Cod : Integer;
begin
    

    // Contador de Código 
    DM.qry_autcod.Open;
    DM.qry_autcod.SelectSQL.Clear;
    DM.qry_autcod.SelectSQL.add(´SELECT (MAX(CODIGO) + 1 ) PROX FROM AUTORES ´);
    dm.qry_autcod.open;
    cod := dm.qry_autcod.fields[0].AsInteger;
    DM.qry_autcod.Close;
    
    Edit_Codigo.Text := IntToStr(cod);
end;



Ela da certo, porem sómente quando ja tenho um valor inicial, por que quando a tabela esta vazia esse codigo retorna NULL e nao envia o numero 1 para o primeiro registro da tabela quando vou inserir o mesmo...
Voce nao saberia me dizer como posso fazer uma verificação, caso a tabela esteja vazia (NULL) entao gera o primeiro código?


Responder

Gostei + 0

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar