Fórum Numeração sequecial. Não chave primária. #350936
21/12/2007
0
CREATE GENERATOR ID_LANCAMENTO_PROJETO; CREATE TABLE LANCAMENTO_PROJETO ( ID_LANCAMENTO_PROJETO INTEGER NOT NULL, COD_PROJETO_LANCAMENTO VARCHAR(6), COD_ORDENADO_M VARCHAR(20) NOT NULL, COD_GRUPO_FK INTEGER NOT NULL, ITEM INTEGER, QUANTIDADE_M VARCHAR(20), TOTAL NUMERIC(15,2) );
Tô querendo que o campo ´ITEM´ seja sequencial. Para cada ´COD_PROJETO_LANCAMENTO´ tenha uma sequência separada.
Como faço isso?
[/code]
Jpauloss
Curtir tópico
+ 0Posts
21/12/2007
Delphijean
Acho que basta vc crirar um generator, como si vem estivesse usando numa primary key mesmo que nao seja.
espero ter ajudado, se não detalhe melhor suma necessidade.
Gostei + 0
22/12/2007
Micheus
Vc faz uma consulta na sua tabela LANCAMENTO_PROJETO, filtrando o código ID_LANCAMENTO_PROJETO e pegando o MAX do ITEM somado a 1:
select MAX(ITEM) AS ITEM
from LANCAMENTO_PROJETO
where ID_LANCAMENTO_PROJETO = :ID_LANCAMENTO_PROJETO
- passa como parâmetro o ID do projeto e abre a consulta;
- pega o resulta e soma 1 e atribui ao no ITEM desde projeto.
está aí o sequêncial por projeto.
Gostei + 0
28/12/2007
Jpauloss
Vc faz uma consulta na sua tabela LANCAMENTO_PROJETO, filtrando o código ID_LANCAMENTO_PROJETO e pegando o MAX do ITEM somado a 1:
select MAX(ITEM) AS ITEM
from LANCAMENTO_PROJETO
where ID_LANCAMENTO_PROJETO = :ID_LANCAMENTO_PROJETO
- passa como parâmetro o ID do projeto e abre a consulta;
- pega o resulta e soma 1 e atribui ao no ITEM desde projeto.
está aí o sequêncial por projeto.[/quote:ccbc835a27]
e o valor +1 fica como na prática pode me dar um exemplo com base nesse mesmo que vc colocou?
Gostei + 0
28/12/2007
Micheus
em termos de programação Delphi:
... Query1.SQL.Clear; Query1.SQL.Add(´select MAX(ITEM) AS ITEM´); Query1.SQL.Add(´from LANCAMENTO_PROJETO´); Query1.SQL.Add(´where ID_LANCAMENTO_PROJETO = :ID_LANCAMENTO_PROJETO´); Query1.ParamByName(´ID_LANCAMENTO_PROJETO´).AsInteger := <valor do campo>; Query1.Open; Novo_ID_ITEM := Query1.FieldByName(´ITEM´).AsInteger +1; Query1.Close; ...
Este procedimento deve ser realizado no evento BeforePost do dataset para tentar deixar para o último momento a obtenção deste código.
Espero ter melhorado a explicação.
Gostei + 0
30/12/2007
Jpauloss
em termos de programação Delphi:
... Query1.SQL.Clear; Query1.SQL.Add(´select MAX(ITEM) AS ITEM´); Query1.SQL.Add(´from LANCAMENTO_PROJETO´); Query1.SQL.Add(´where ID_LANCAMENTO_PROJETO = :ID_LANCAMENTO_PROJETO´); Query1.ParamByName(´ID_LANCAMENTO_PROJETO´).AsInteger := <valor do campo>; Query1.Open; Novo_ID_ITEM := Query1.FieldByName(´ITEM´).AsInteger +1; Query1.Close; ...
Este procedimento deve ser realizado no evento BeforePost do dataset para tentar deixar para o último momento a obtenção deste código.
Espero ter melhorado a explicação.[/quote:744ff9bc1b]
NOVO_ID_ITEM é o que?
Gostei + 0
02/01/2008
Micheus
Voce pode considerá-la uma variável do tipo Integer, mas também pode ser o campo do seu dataset para o qual vc quer gravar o novo código gerado.
Gostei + 0
03/01/2008
Jpauloss
Micheus meu código ta assim
function TF_LANCAMENTO_PROJETO.incrementa_item: string; var novo_item :Integer; begin //**para auto incremento do item por cod_projeto_lancamento**// dm.sdsLancamentoItem.Close; dm.sdsLancamentoItem.CommandText:=´select max(item) as item ´ + ´from lancamento_projeto ´ + ´where cod_projeto_lancamento = :cod_projeto_lancamento´; dm.sdsLancamentoItem.ParamByName(´cod_projeto_lancamento´).AsString:=projeto.Text; dm.sdsLancamentoItem.Open; novo_item:=dm.sdsLancamentoItem.fieldbyname(´ITEM´).AsInteger+1; item.Text:=IntToStr(novo_item); dm.sdsLancamentoItem.Close; end;
Ta funcionando só que está pulando de dois em dois ficando assim:
1
1
2
2
3
3
4
4
Ele fica repetindo o número mais uma vez.
Tem como acertar?
Tem como colocar isso num SP? Como faço?
Gostei + 0
03/01/2008
Micheus
donde penso que vc está obtendo o código e mostrando na tela antes mesmo de concluir a inclusão dos novos dados. Esta atitude pode não garantir a existência de um único código, já que se mais que um usuário estiverem editando o mesmo registro, podem obter o mesmo número. O ideal é que este número seja apenas obtido no momento da gravação;
- Observei também que vc não atribui o valor obtido ao resultado da sua função [i:07af9bb1de]incrementa_item[/i:07af9bb1de]; O que vc está fazendo com o valor retornado pela função?
Quanto a esta estranha duplicação, não teria como dar um palpite sem saber como vc está tratando/gravando esta informação.
Por acaso, após gravar a informação vc está ´comitando´ a transação?
Quanto a colocar em uma SP, poderia sim. Qual banco vc está utilizando?
Basicamente vc criaria ela, definindo um parâmetro de entrada ([i:07af9bb1de]cod_projeto_lancamento[/i:07af9bb1de]) e um de saída ([i:07af9bb1de]ITEM[/i:07af9bb1de]).
Se sua intenção com esta numeração do ITEM ser seqüêncial para cada lançamento, vale lembrar que, caso seja excluído algum destes itens posteriormente, haverá uma lacuna na seqüência.
Abraços
Gostei + 0
03/01/2008
Jpauloss
Micheus meu botão de gravar está assim
procedure TF_LANCAMENTO_PROJETO.gravarClick(Sender: TObject);
begin
if (projeto.Text=´´) or (grupo.text=´´) or (cod.Text=´´) or (qt.Text=´´) then begin ShowMessage(´Preencha dados básicos!´); exit end else begin
Try
transacao.TransactionID:=1;
transacao.IsolationLevel:= xilREPEATABLEREAD;
dm.Conexao.StartTransaction(transacao);
dm.sdsLancamento.Close;
dm.sdsLancamento.CommandText:=´insert into lancamento_projeto (cod_projeto_lancamento,´ +
´cod_grupo_fk, cod_ordenado_m, quantidade_m,´+
´total, item) values (:cod_projeto_lancamento, ´ +
´:cod_grupo_fk, :cod_ordenado_m, :quantidade_m, :total, :item)´;
dm.sdsLancamento.ParamByName(´cod_projeto_lancamento´).AsString:=projeto.Text;
dm.sdsLancamento.ParamByName(´cod_grupo_fk´).AsString:=grupo1.Text;
dm.sdsLancamento.ParamByName(´cod_ordenado_m´).AsString:=cod.Text;
dm.sdsLancamento.ParamByName(´quantidade_m´).AsString:=qt.Text;
dm.sdsLancamento.ParamByName(´total´).AsFloat:=StrToFloat(total.Text);
dm.sdsLancamento.ParamByName(´item´).AsString:=item.Text;
incrementa_item;{**para fazer auto incremento do campo ´ITEM´**}
dm.sdsLancamento.ExecSQL;
dm.Conexao.Commit(transacao);
grupoChange(Sender);
Except
on Exc:Exception do
Begin
ShowMessage(´Ocorreu um erro na tentativa de inclusão de registro:´+Exc.Message);
dm.Conexao.Rollback(transacao);
end;
end;
end;
end;E a função é essa que postei.
O banco de dados que utilizo é firebird2.0
Com relação ao que vc disse
Tem jeito de quando deletar um registro fazer um update para alterar todas as sequencias gravadas?
Valeu, fico no aguardo.
Gostei + 0
03/01/2008
Micheus
...
dm.sdsLancamento.ParamByName(´item´).AsString:=item.Text;
incrementa_item;{**para fazer auto incremento do campo ´ITEM´**}
dm.sdsLancamento.ExecSQL;
...é que como está seu código, se vc em algum outro momento inicializou ele, poderia ocorrer o seguinte:
- vc inicializa [i:9e948116f3]item.Text[/i:9e948116f3], logo ele recebe o texto ´1´;
- daí, vc atribui este valor ao parâmetro antes de gravar o registro;
- então, vc chama a funçao [i:9e948116f3]incrementa_item[/i:9e948116f3] que irá obter o máximo e somar 1, o que neste caso, ainda será retornado ´1´ e atribuirá ao [i:9e948116f3]item.Text[/i:9e948116f3];
- em seguida vc grava o registro, e o campo ITEM terá o valor ´1´ no banco;
próxima inclusão, observando o código que aqui está:
- da inclusão anterior, [i:9e948116f3]item.Text[/i:9e948116f3] ficou com o texto ´1´;
- daí, vc atribui este valor ao parâmetro antes de gravar o registro;
- então, vc chama a funçao [i:9e948116f3]incrementa_item[/i:9e948116f3] que irá obter o máximo e somar 1, o que neste caso, retornará ´2´ e atribuirá ao [i:9e948116f3]item.Text[/i:9e948116f3];
- em seguida vc grava o registro, e o campo ITEM terá o valor ´1´ no banco, já que [i:9e948116f3]item.Text[/i:9e948116f3] coninha ´1´ antes de vc chamar a funçao [i:9e948116f3]incrementa_item[/i:9e948116f3] (como mencionei na linha anterior);
Neste cenário, temos gravados dois itens ´1´!
Ou vc obtém o valor máximo antes de gravar o registro e atribui ele ao parâmetro, ou então vc obtém ele ao criar o novo registro para edição e não chama a funçao [i:9e948116f3]incrementa_item[/i:9e948116f3] na hora de gravar, há que [i:9e948116f3]item.Text[/i:9e948116f3] já conterá o nº do item desejado.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)