gerar código automáticamente
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:
----------------------------------
tabela
-------
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
Curtidas 0
Respostas
Rjun
31/08/2005
Faça um select que retorno o maior valor do campo código.
SELECT MAX(Codigo) FROM Autores
GOSTEI 0
Mahdak
31/08/2005
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????
GOSTEI 0
Rjun
31/08/2005
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;
GOSTEI 0
Michelli88
31/08/2005
Nao deu certo porque isso:
Vai retornar quantos registros foram alterados, e nao o codigo!
faz assim:
;-)
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;
;-)
GOSTEI 0
Gandalf.nho
31/08/2005
Qual é o banco de dados?
GOSTEI 0
Mahdak
31/08/2005
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;
GOSTEI 0
Motta
31/08/2005
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 !!
GOSTEI 0
Mahdak
31/08/2005
[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);
GOSTEI 0
Motta
31/08/2005
// 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);
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);
GOSTEI 0
Gandalf.nho
31/08/2005
Se seu banco é Firebird, pq não usa generator?
GOSTEI 0
Mahdak
31/08/2005
// 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...
GOSTEI 0
Mahdak
31/08/2005
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!
GOSTEI 0
Mahdak
31/08/2005
[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);
GOSTEI 0
Michelli88
31/08/2005
La no IBDataset, tem a propriedade GeneratorField voce vai ter ligar o GenId e o campo que vai receber os codigos gerados!
GOSTEI 0
Mahdak
31/08/2005
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:
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?
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?
GOSTEI 0
Gandalf.nho
31/08/2005
Só uma pergunta, é obrigatório vc não ter buracos na sua numeração (como notas fiscais e similares)? Se não, use generator mesmo que é muito mais simples e garante que não haverá dois números iguais.
GOSTEI 0
Mahdak
31/08/2005
Só uma pergunta, é obrigatório vc não ter buracos na sua numeração (como notas fiscais e similares)? Se não, use generator mesmo que é muito mais simples e garante que não haverá dois números iguais.
Gandalf, nao posso ter furos por que gero etiquetas sequenciais, entao se houver furos na numeração haverá disperdicio de etiquetas.... caso contrario tambem achei o Generator bem interessante e muito mais funcional e facil de usar, porem acho que esse nao seria o meu caso...
o que vc acha?
GOSTEI 0