Por que Minha trigger não dispara ?

Firebird

16/08/2003

Caro amigo!
Uso D6 + IB/FB + DBExpress.
Criei minha tabela com o nome: DESP_VARIAVEIS.
Criei uma Generation com o nome GNT_DESPV, inicializada com zero.

create generator GNT_DESPV;
set generator GNT_DESPV to 0;

Criei na sequencia minhas Triggers, veja abaixo.
Mas quando crio um registro no arquivo, o campo
CODMOV não é carregado, porque minha trigger não dispara.
Então o q estou fazendo de errado?

A quem responder, desde já meus agradecimentos.

ANT.CARLOS/SP
T+

Favor fazer um comentário, pois estou migrando p/ IB/FB.




Obs: Criei duas p/ fazer um teste, pois nenhuma funciona.
//=============================================//

/* Triggers only will work for SQL triggers */

CREATE TRIGGER ´TRG_DESPV´ FOR ´DESP_VARIAVEIS´
ACTIVE BEFORE INSERT POSITION 0
AS
DECLARE VARIABLE sequencial INTEGER;
BEGIN
IF (NEW.CODMOV IS NULL) THEN
begin
select max(CODMOV) from DESP_VARIAVEIS into sequencial;
if (sequencial is null) then
begin
sequencial=0;
end
sequencial=:sequencial+1;
NEW.CODMOV = sequencial;
end
END
^

//===========================================//

CREATE TRIGGER ´TRG_DESPV2´ FOR ´DESP_VARIAVEIS´
ACTIVE BEFORE INSERT POSITION 0
AS
BEGIN
IF (NEW.CODMOV IS NULL) THEN
NEW.CODMOV = GEN_ID(GNT_DESPV,1);
END
^

COMMIT WORK ^
SET TERM ;^

//============================================//


Ant.carlos/sp

Ant.carlos/sp

Curtidas 0

Respostas

Afarias

Afarias

16/08/2003

Claro q ambas funcionam (a 1ª eu não use nunca num sistema multi-usuário) -- o campo CODMOV está realmente indo NULLO ??

Se está, então acredito q o q vc está querendo dizer é q o valor não aparece no cliente -- pois se o valor é gerado no servidor, como o cliente pode ficar sabendo?? Vc tem q fechar e abrir sua consulta para ver o valor gerado.


T+


GOSTEI 0
Ant.carlos/sp

Ant.carlos/sp

16/08/2003

Caro amigo!
O q está acontecendo, é q campo CODMOV não está sendo carregado.
Pois ao gravar, é gerado um erro de q o campo CODMOV tem
q ser preenchido pois ele é a chave.
Então, o q deve estar acontecendo.
Pois até agora não consegui fazer nenhuma trigger rodar.

ANT.CARLOS/SP


GOSTEI 0
Afarias

Afarias

16/08/2003

Vc não falou sobre a mensagem de erro (e agora nem disse que erro é) -- fica difícil ajudar se vc não mostra os fatos como são.

O Erro (apesar de vc não dizer) acredito q seja um erro gerado pelo TField q provavelmente está com a propriedade REQUIRED = TRUE , isto é verificado no Cliente e nào tem como o Interbase ter nada com isso.

Configure sua propriedade como REQUIRED = FALSE (TField) para o campo q será preenchido no servidor (ou preencha algum valor tipo -1 -- sendo q neste caso as triggers não podem ter o código de verificação se é nulo).

De qualquer forma, deixa eu te dar uma dica... mesmo quando vc conseguir fazer isso ai funcionar, provavelmente vai descobrir que não é isso q vc quer (a maioria do pessoal é assim)...

apague as triggers e simplesmente use a propriedade GeneratorField do IBDataSet ou IBQuery. --- se não for seu caso, esqueça!


T+


GOSTEI 0
Ant.carlos/sp

Ant.carlos/sp

16/08/2003

USO (D6 + IB/FB + DbExpress)

Trio TSQLQuery + DSProvider + ClienteDataSet

O campo CODMOV é uma chave NOT NULL.

Ao gravar, uma msg é apresentada:

´Field CODMOV munst have a value´

Desabilitei o Requerido do campo CODMOV = false tanto TSQLQuery
com no ClienteDataSet.

Tirei o (NEW.CODMOV = IS NULL) da Trigger,
e funcionou.

Mas tive q após o ApplyUpdate, fechar e abrir o
ClienteDataSet, pois senão, dava um erro de chave duplicada ao gravar
o próximo registro.

Grato!
T+


GOSTEI 0
Afarias

Afarias

16/08/2003

1 - Use sempre GENERATORS para gerar códigos únicos em sistemas multi-usuário

2 - para não ter q fechar/abrir seu CDS para ver o código gerado no servidor, desista das triggers e carregue um novo valor do generator a partir do seu aplicativo (em um dos eventos: OnNewRecord, BeforePost do CDS ou no evento BeforeUpdateRecords do Provider)

a query para pegar im novo código é::

select gen_id(nome_generator, 1) from rdb$database;


T+


GOSTEI 0
Ant.carlos/sp

Ant.carlos/sp

16/08/2003

Olá!
Afarias.
Esta form de buscar o valor na Generation, é
muito útil.
Fiz o teste e a Generation foi incrementada.
Mas como pego o valor de retorno ?

=============== VC mandou ===========
a query para pegar o novo código é::

select gen_id(nome_generator, 1) from rdb$database;

===================================

Qry_Pesq.Close;
Qry_Pesq.CommandText := ´SELECT GEN_ID(GNT_ITENSVD,1) FROM rdb$database´;
Qry_Pesq.Open;


ANT.CARLOS/SP


GOSTEI 0
Afarias

Afarias

16/08/2003

Oi Antônio, Blz?!

Para obter o valor de retorno, acesso o campo da Query (ou do CDS como está fazendo, más neste caso, vc não precisa usar um CDS associado a Query, basta apenas a Query), EX::

var
NovoCodigo: Integer;

{...}

with Qry_Pesq do
begin
Close;
CommandText := ´SELECT GEN_ID(GNT_ITENSVD,1) FROM rdb$database´;
Open;
NovoCodigo := Fields[0].AsInteger; // fields[0] retorna o TField
//(campo) de índice 0 (o primeiro) -- como só tem 1 :D
end;

ou com a TSQLQuery ::

with TSQLQuery1 do
begin
SQL.Text := ´select bla bla bla´;
Open;
NovoCodigo := Fields[0].AsInteger;
end;

(como não uso DBX tô imaginando que SQLQuery seja semelhante a outros componentes Query)

vc podia tb dar nome ao campo (AS ...) e usar o FieldByName más não é necessário.


T+


GOSTEI 0
Ant.carlos/sp

Ant.carlos/sp

16/08/2003

Olá!
Afarias.
Testei novamente a rotinas p/ pegar o valor do Generation.
O Generation é incrementado, mas a query nao retorna nenhum
registro e causa um erro.

ERRO:
============
Project Project.exe raised exception class EcovertError With message
´´ is not a valid Integer value.
Process Stoped.


Minha Query:
============
Qry_Pesq.Close;
Qry_Pesq.CommandText := ´SELECT GEN_ID(GNT_ITENSVD,1) FROM RDB$DATABASE´;
Qry_Pesq.Open;

Qry_Pesq.RecordCount; //...VErifiquei q a Qry esta vazia

NovoCodigo := Qry_Pesq.Fields[0].AsInteger;

Então o q está errado?

Desde já meus agradecimentos.

ANT.CARLOS/SP


GOSTEI 0
Afarias

Afarias

16/08/2003

Não sei...

Se vc está usando um ClientDataSet para esta operação, aconselho q não use, não é necessário. Use apenas uma QUERY (TSQLQuery eu acho)::

Provavelmente o componente não esteja dando um FETCH nos registros para seu Buffer -- neste caso vc pode forçar este Fetch com um First, Next, Last, FetchAll ou algo assim. Se for um CDS simplesmente coloque o FetchOnDemand = FALSE.

T+


GOSTEI 0
Ant.carlos/sp

Ant.carlos/sp

16/08/2003

Olá!

Consegui fazer a pesquisa no Generation.
O q estava faltando, era abrir o Fields Editor e incluir o campo.
Opós isso e duras baterias de teste, consegui fazer funcionar.

Qry_Pesq.Close;
Qry_Pesq.Open;
Codseq := Qry_PesqGEN_ID.AsInteger;
Codseq := Qry_Pesq.Fields[0].AsInteger;

Grato!
T+

ANT.CARLOS/SP


GOSTEI 0
POSTAR