ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Aprendendo a usar Trigger!
Ir à página 1, 2  Próximo
 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Ter Jan 09, 2007 10:08 pm    Assunto: Aprendendo a usar Trigger! Responder com Citação

Pessoal ainda nao testei, estou querendo aprender a usar as trigger, entao fiz essa trigger:

Código:
CREATE TRIGGER RESTRICAOVALORTBCONTA FOR TBCONTA
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  /* Trigger Para nao ficar valor null*/
  if (NEW.VALOR IS NULL) then
    Exception RESTRICAO;
end


A ideia eh para criar uma restriçao aonde nao pode incluir valores nulos no campo valor da tabela, a restricao ja criei no Exception do IBExpert, entao gostaria de saber se esta certo essa Trigger?

Agradeço a opniao de todos.
Adriano.

E tambem se puderem me explicar, se eh melhor usar trigger, em vez de usar codigos dentro da unit do delphi! Ou seja eu posso muito bem fazer um codigo de restriçao no evento onexit do componente, mais gostaria da opnião do pessoal, se eh mais vantajoso usar na trigger ou no programa mesmo.

---------------------EDITANDO-----------------------
Mais uma pergunta essas triger ela dispara somente na hora em que vou gravar no banco ou tem como disparar antes? Como faço no evento onexit dentro do delphi.

Ainda mais uma pergunta: Tenho uma tabela com campos assim

tabmovimento
sequencia
conta
descricao
valor

e outra tabdebido(tabela filha)
sequencia (FK) (Refernecia com a tabela tabmovimento)
conta_D
descricao
valor

E na hora em que eu for gravar no form vai gravar na tabmovimento o que eu digitar no form, a pergunta seria como posso gravar tambem os mesmos dados na tabela (filha)? Preciso ao mesmo tempo fazer um codigo para as duas tabelas tipo assim

insert into tabmovimento
....
parambyname('campos').AsString:=editConta;
execsql

insert into tabdebito
...
parambyname('campos').AsString:=editConta;
execSQL

Ou tem como fazer somente em uma tabela e a outra ja receber o resultado?

Abçs;
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qua Jan 10, 2007 2:26 pm    Assunto: Responder com Citação

A trigger está correta. Quanto a escolher onde usar o q, depende muito de cada um. Contudo, restrições do tipo dessa (verificar se valores estão varios), verificação de CPF/CNPJ compensam serem feitas na aplicação, pois reduz o tráfego de dados na rede. E para garantir a integridade, crie o campo como not null.

A trigger só dispara nos determinados eventos do BD, ou seja, antes ou após de inserir/alterar/excluir.

Se quiser que dispare em outros momentos, o interessante é usar uma Stored Procedure, que também pode ser disparada por uma trigger através da instrução

EXECUTE PROCEDURE NomeDaProcedure( [Parametros] );

Citação:
... Ou tem como fazer somente em uma tabela e a outra ja receber o resultado?

Tem se você criar uma Stored Procedure que faça isso. Uma que pegue o numero da conta, e já verifique a existência na tabela mestre, no caso de não haver a linha, insere na tabela mestre, e depois insere na tabela detalhe. Note que será necessário existir uma linha correspondente na tabela mestre (devido ao índice) para que se possa ter uma linha válida na tabela detalhe.
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 10, 2007 2:43 pm    Assunto: Responder com Citação

Obrigado por responder Thomazs.

Bom no primeiro caso entao eh mais conviniente usar em algum evento de um edit entao?

Sobre SProcedure;
Citação:
em se você criar uma Stored Procedure que faça isso. Uma que pegue o numero da conta, e já verifique a existência na tabela mestre, no caso de não haver a linha, insere na tabela mestre, e depois insere na tabela detalhe. Note que será necessário existir uma linha correspondente na tabela mestre (devido ao índice) para que se possa ter uma linha válida na tabela detalhe.

Gostei da ideia, porem nao sei nem como criar uma Stored Procedure para esse evento.

Vc tem um pequeno exemplo de como fazer isso amigo?

Outra pergunta amigo, aonde eh melhor usar restriçoes entao?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qua Jan 10, 2007 3:19 pm    Assunto: Responder com Citação

Citação:
Bom no primeiro caso entao eh mais conviniente usar em algum evento de um edit entao?

Para o caso que você mencionou sim. Ou no evento do edit, ou no momento de salvar.

Citação:
Outra pergunta amigo, aonde eh melhor usar restriçoes entao?

Depende do tipo de restrição a que você se refere. Por exemplo, se essa restrição exije busca no banco e tal, é melhor deixar a restrição no proprio banco. Isso pode aparentemente "bagunçar" um pouco o projeto, pois algumas restrições estariam na aplicação e outras no banco, mas isso pode ser contornado com a documentação.

Citação:
Vc tem um pequeno exemplo de como fazer isso amigo?

Supondo que a estrutura da tabela fosse:

Mestre
----------------
Codigo - Integer
Descricao - Varchar(50)
Data - Date

Detalhe
----------------
Cod_Mestre - Integer
Cod_Produto - Integer
Quantidade - Integer

Código:

Set term ^ ;
create procedure GravaDados(
       Cod_Mestre Integer,
       Desc_Mestre varchar(50),
       Data_Mestre Date,
       Cod_Produto Integer,
       Quantidade Integer
)
as
begin
  if ( not exists(select codigo from Mestre where codigo = :Cod_Mestre) )then
    Insert into Mestre Values ( Cod_Mestre, Desc_Mestre, Data_Mestre );
  Insert into Detalhe Values (Cod_Mestre, Cod_Produto, Quantidade );
end
^
Set Term ; ^


Esse seria um exemplo simples do que se pode fazer, mas pode-se variar as regras e tal.
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 10, 2007 3:40 pm    Assunto: Responder com Citação

Sim Thomazs, estou entendendo, mais primeiro gostaria de saber aonde eu crio essa procedure

tentei no IBExpert com o botao direito na opçao procedure~e ger a seguinte DLL
Código:
SET TERM ^ ;

CREATE PROCEDURE NEW_PROCEDURE
AS
begin
  /* Procedure Text */
  if ( not exists(select codigo from Mestre where codigo = :Cod_Mestre) )then
    Insert into Mestre Values ( Cod_Mestre, Desc_Mestre, Data_Mestre );
  Insert into Detalhe Values (Cod_Mestre, Cod_Produto, Quantidade );
  suspend;
end^

SET TERM ; ^

GRANT SELECT,INSERT ON MESTRE TO PROCEDURE NEW_PROCEDURE;

GRANT INSERT ON DETALHE TO PROCEDURE NEW_PROCEDURE;


Pq nao apareçe assim
Citação:
Set term ^ ;
create procedure GravaDados(
Cod_Mestre Integer,
Desc_Mestre varchar(50),
Data_Mestre Date,
Cod_Produto Integer,
Quantidade Integer
)
Ou aonde devo colocar isso ou eh somente o modelo da Table?


Outra pergunta no delphi eu uso parametros para incluir, deletar, update.

Para incluir uso parambyname('campo').As.....:-edit(x).text;
Na stored prodeure nao precisa?

Mais uma pergunta depois que eu salvar essa stored procedure como eu a chamo do form?

Desculpe tantas perguntas amigo, mais nao sei nada a respeito disso, eh como se eu tivesse na primeira aula ... hehehehe Very Happy

Outra coisa que eu isa esqueçendo
Esse campo da tabela detalhe
cod_mestre = tem que fazer referencia com o campo codigo da tabela mestre? Pois a minha ideia eh deletar em cascata depois.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qua Jan 10, 2007 6:14 pm    Assunto: Responder com Citação

Citação:
...Ou aonde devo colocar isso ou eh somente o modelo da Table?

Não é um modelo da tabela... é o código da procedure mesmo. O que ocorre é que quando você usa o IBExpert ele cria um tipo de assistente, para facilitar a construção da procedure. Por exemplo, os campos Cod_Mestre, Desc_Mestre, etc... devem ser colocados em Parametros de Entrada. Existe um local onde você coloca o nome da procedure a ser criada (que por padrão é NEW_PROCEDURE). Se você quiser digitar toda a sintaxe de criação da procedure, abra um Script Executive e digite lá dentro todos os comandos de criação (que se iniciam e terminam no Set Term...).



Citação:
...Na stored prodeure nao precisa?

Precisa. Tanto é que os valores de Cod_Mestre, Desc_Mestre, etc, devem ser passados pelo usuários. Eles são parâmetros de entrada da procedure.



Citação:
Mais uma pergunta depois que eu salvar essa stored procedure como eu a chamo do form?

Vai depender dos componentes que você tiver usando. Pode ser usando um IBStoredProc, SqlStoredProc, IbQuery, etc.
A diferença é que, nos *StoredProc você coloca o nome da procedure apenas, e nas Query's você tem que colocar o comando de execução, ou seja:
Código:
EXECUTE PROCEDURE SuaProcedure( Parametros );




Citação:
Outra coisa que eu isa esqueçendo
Esse campo da tabela detalhe
cod_mestre = tem que fazer referencia com o campo codigo da tabela mestre? Pois a minha ideia eh deletar em cascata depois.

Sim. Ele faz referência. Se você notar, o valor de Cod_Mestre na procedure, é usado na inserção do valor do Codigo na Tabela Mestre, caso o mesmo não exista. E o mesmo valor é inserido na tabela Detalhe. Quanto a exclusão em cascata, se tiver criada a ForeignKey, ele faz isso automaticamente (desde que definido como cascade).
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qua Jan 10, 2007 10:18 pm    Assunto: Responder com Citação

Obrigado Marcos Thomazs, agora acho que ja estou aprendendo um pouco mais sobre SProc e Trigger Very Happy

Olha como ficou o resultado final
a Stored Procedure
Código:
SET TERM ^ ;

CREATE PROCEDURE GRAVADADOS (
    SEQUENCIA INTEGER,
    CONTA VARCHAR(15),
    HISTORICO VARCHAR(100),
    VALOR NUMERIC(15,2),
    CONTAD VARCHAR(15))
AS
begin
if ( not exists(select * from tbconta where sequencia = :sequencia) )
  then
  begin
   Insert Into tbconta (sequencia, conta, historico, valor) Values (:sequencia, :conta, :historico, :valor);

   Insert into debito (sequencia, contad, historico, valor) Values ( :sequencia, :contad, :historico, :valor );
   end
end^

SET TERM ; ^

GRANT SELECT,INSERT ON TBCONTA TO PROCEDURE GRAVADADOS;

GRANT INSERT ON DEBITO TO PROCEDURE GRAVADADOS;

GRANT EXECUTE ON PROCEDURE GRAVADADOS TO SYSDBA;


e como chamo a Stored Procedure no IBQuery
Código:
if application.messagebox(PChar('Deseja Gravar esta Nota?'), PChar('Incluir Dados'+Self.Caption),MB_IConquestion +MB_YesNo)=IDYES then
begin
with dm.QStoredProc do
 begin
   close;
   SQL.clear;
   sql.add('EXECUTE PROCEDURE GRAVADADOS (:SEQUENCIA, :CONTA, :HISTORICO, :VALOR, :CONTAD)');
   ParamByName('conta').AsString:=e1.text;
   ParamByName('historico').AsString:=r1.text;

   svalor := stringreplace(e3.text, '.', '', [rfReplaceAll]);
   svalor := stringreplace(svalor, ',', '.', [rfReplaceAll]);

   ParamByName('valor').Value:=sValor;

   ParamByName('contad').asString:=e1.text;
try
   ExecSQL;
   tansaction.commit;
...
...
except
...
...


Valeu amigo, muito obrigado mesmo por me ajudar.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qui Jan 11, 2007 1:31 pm    Assunto: Responder com Citação

Por nada amigo... só que tem 1 porém... se entendi bem, uma Conta pode ter vários Débitos é isso?

Se for, não precisa do Begin/End do IF... isso porque, é verificada a existência da linha na tabela Mestre (Conta). Se não existir, é então criada a linha. Mas existindo ou não a linha na tabela Mestre, a linha da tabela Detalhe (Débito) deve ser inserida. Se esse meu pensamento estiver correto, você deve tirar o Begin/End do IF.
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qui Jan 11, 2007 2:12 pm    Assunto: Responder com Citação

thomazs escreveu:
Por nada amigo... só que tem 1 porém... se entendi bem, uma Conta pode ter vários Débitos é isso?

Se for, não precisa do Begin/End do IF... isso porque, é verificada a existência da linha na tabela Mestre (Conta). Se não existir, é então criada a linha. Mas existindo ou não a linha na tabela Mestre, a linha da tabela Detalhe (Débito) deve ser inserida. Se esse meu pensamento estiver correto, você deve tirar o Begin/End do IF.
Sim, a conta vai ter varios debitos sim, entao vou verificar esta parte

Eh o seguinte isso vai ser uma tabela meste(movimento da contabilidade) aonde que vai existir duas tabelas casadas a tabela movimento (debito, credito) assim vou fazer um lançamento soh em tres tabelas.

Agora me surgiu um outro problema amigo
Veja a IBQuery : Atençao sobre a linha em vermelho
Citação:
if application.messagebox(PChar('Deseja Gravar este Lançamento?'), PChar('Incluir Dados'+Self.Caption),MB_IConquestion +MB_YesNo)=IDYES then
begin
with dm.QStoredProc do
begin
close;
SQL.clear;
sql.add('EXECUTE PROCEDURE SP_GRAVACONTA (:SEQUENCIA, :CONTA, :HISTORICO, :VALOR, :CONTAD, :MES, :ANO, :DATA)');
sql.add('WHERE Extract(Month FROM DATA) = :mes and Extract(Year FROM DATA) = :ano');

ParamByName('conta').AsString:=e1.text;
ParamByName('historico').AsString:=r1.text;

svalor := stringreplace(e3.text, '.', '', [rfReplaceAll]);
svalor := stringreplace(svalor, ',', '.', [rfReplaceAll]);

ParamByName('valor').Value:=sValor;

ParamByName('contad').asString:=e1.text;
ParamByName('mes').value:=uppercase(formatdatetime('MM',(STRTODATE(edit5.TEXT))));
Parambyname('ano').asinteger := StrToInt(FormatDateTime('YYYY',StrToDate(Edit5.text)));
ParamByName('data').value:=edit5.text;
try
ExecSQL;
dm.tLconta.Active:=true;
dm.tLConta.Commit;

close;
sql.clear;
sql.add('select * from tbconta');
sql.add('WHERE Extract(Month FROM DATA) = :mes and Extract(Year FROM DATA) = :ano');
sql.add('order by sequencia');
Parambyname('mes').asinteger := StrToInt(FormatDateTime('MM',StrToDate(Edit5.text)));
Parambyname('ano').asinteger := StrToInt(FormatDateTime('YYYY',StrToDate(Edit5.text)));
open;
dm.Tbconta.FetchAll;
eNR.Caption := IntToStr(dm.tbconta.RecordCount);

except
on E:Exception do
begin
dm.tlconta.RollBack;
sbar.SimpleText:='Abortado';
ShowMessage('Falha na Inclusão dos Dados!'#13#10' Mensagem: '+E.Message);
end;

end;

end;
Esta gerando erro nesta linha em vermelho aonde quero uma condiçao feito no where

Pra dizer a verdade esta a maior bagunça a passagem destes parametros, nao esta obedeçendo o que esta no edit, maskedit, etc...


A SP tambem mudei assim
Código:
SET TERM ^ ;

CREATE PROCEDURE SP_GRAVACONTA (
    SEQUENCIA INTEGER,
    CONTA VARCHAR(15),
    HISTORICO VARCHAR(100),
    VALOR NUMERIC(15,2),
    MES VARCHAR(2),
    ANO VARCHAR(4),
    CONTAD VARCHAR(15),
    DATA DATE)
AS
begin
if ( not exists(select * from tbconta where sequencia = :sequencia) )
  then
  begin
   Insert Into tbconta ( sequencia, conta, historico, valor, mes, ano, DATA ) Values ( :sequencia, :conta, :historico, :valor, :mes, :ano, :DATA );

   Insert into debito ( sequencia, contad, historico, valor, mes, ano, DATA ) Values ( :sequencia, :contad, :historico, :valor, :mes, :ano, :DATA );
   end
end^

SET TERM ; ^

GRANT SELECT,INSERT ON TBCONTA TO PROCEDURE SP_GRAVACONTA;

GRANT INSERT ON DEBITO TO PROCEDURE SP_GRAVACONTA;

GRANT EXECUTE ON PROCEDURE SP_GRAVACONTA TO SYSDBA;



Outra pergunta:
Eu li a respeito que o Firebird tem algumas limitaçoes tipo
Tamanho maximo do banco de dados ------> 7TB
Numero maximo de conexões ---------->1024

Entao a pergunta: O que vem a ser isso? Serah que o Firebird nao aguenta muitos dados em seu banco?

Mais uma vez agradeço por estar me ajudando Thomazs.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qui Jan 11, 2007 6:26 pm    Assunto: Responder com Citação

adriano_servitec escreveu:
Esta gerando erro nesta linha em vermelho aonde quero uma condiçao feito no where

Amigo, o execute procedure não possui clausula Where. Where é usado para Update, Delete e Select. Se quiser acrescentar alguma restrição a execução da procedure, faça dentro do código da propria procedure, passando o valor como um parâmetro de entrada.

adriano_servitec escreveu:
A SP tambem mudei assim...

O Begin/End ainda permaneceram.

adriano_servitec escreveu:
Outra pergunta:
Eu li a respeito que o Firebird tem algumas limitaçoes tipo
Tamanho maximo do banco de dados ------> 7TB
Numero maximo de conexões ---------->1024
Entao a pergunta: O que vem a ser isso? Serah que o Firebird nao aguenta muitos dados em seu banco?

Quanto ao tamanho máximo, é um tanto quanto complicado dizer, pois isso pode ser uma restrição do sistema operacional, mas de qualquer forma, sendo ou não, devemos concordar que 7 TB é um tamanho considerável (já imaginou como armazenar isso??). Com relação a quantidade de conexões, creio eu não ser uma afirmativa correta. Digo isso porque, fizemos a montagem de um sistema aqui, e tivemos um pequeno problema: o sistema era fechado, mas não fechava a conexão (era um sistema Web). Chegamos a ter mais de 1200 conexões ativas simultâneas, e o banco manteve-se bem, sem queda considerável no desempenho. Não sei se dá pra contar casos como esse, mas enfim, eram conexões ativas.
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qui Jan 11, 2007 6:28 pm    Assunto: Responder com Citação

Olah Thomazs meio problema resolvido (Retirei o campo CONTAD) e esta gravando normal agora.

Da uma olhadinha se precisa de tanto select neste codigo, foi a unica maneira que encontrei para os buttons ficare com enabled true, pois tenho uma rotina que tratabuttons
Código:
if application.messagebox(PChar('Deseja Gravar este Lançamento?'), PChar('Incluir Dados'+Self.Caption),MB_IConquestion +MB_YesNo)=IDYES then
begin
with dm.QStoredProc do
begin
close;
SQL.clear;
sql.add('EXECUTE PROCEDURE SP_GRAVAMOVIMENTO (:SEQUENCIA, :CONTA, :HISTORICO, :VALOR, :MES, :ANO, :DATA)');

ParamByName('conta').AsString:=e1.text;
ParamByName('historico').AsString:=r1.text;

svalor := stringreplace(e3.text, '.', '', [rfReplaceAll]);
svalor := stringreplace(svalor, ',', '.', [rfReplaceAll]);

ParamByName('valor').Value:=sValor;

ParamByName('mes').value:=uppercase(formatdatetime('MM',(STRTODATE(edit5.TEXT))));
Parambyname('ano').asinteger := StrToInt(FormatDateTime('YYYY',StrToDate(Edit5.text)));
ParamByName('data').value:=edit5.text;
try
ExecSQL;
dm.tLconta.Active:=true;
dm.tLConta.Commit;

close;
sql.clear;
sql.add('select * from tbconta');
sql.add('WHERE Extract(Month FROM DATA) = :mes and Extract(Year FROM DATA) = :ano');
sql.add('order by sequencia desc');
Parambyname('mes').asinteger := StrToInt(FormatDateTime('MM',StrToDate(Edit5.text)));
Parambyname('ano').asinteger := StrToInt(FormatDateTime('YYYY',StrToDate(Edit5.text)));
open;
dm.Tbconta.FetchAll;
eNR.Caption := IntToStr(dm.tbconta.RecordCount);

except
on E:Exception do
begin
dm.tlconta.RollBack;
sbar.SimpleText:='Abortado';
ShowMessage('Falha na Inclusão dos Dados!'#13#10' Mensagem: '+E.Message);
end;

end;

end;

end;
with dm.qtbcontalan do
begin
  close;
  sql.clear;
  sql.add('select * from tbconta');
  sql.add('WHERE Extract(Month FROM DATA) = :mes and Extract(Year FROM DATA) = :ano');
  sql.add('order by sequencia desc');
  Parambyname('mes').asinteger := StrToInt(FormatDateTime('MM',StrToDate(Edit5.text)));
  Parambyname('ano').asinteger := StrToInt(FormatDateTime('YYYY',StrToDate(Edit5.text)));
  open;
  dm.Tbconta.FetchAll;
  eNR.Caption := IntToStr(dm.tbconta.RecordCount);
end;
abretabela;
If DM.TBConta.recordcount = 0 then
showmessage('Este banco de dados não contem registros');
E3.TEXT:='';
dm.Tbconta.FetchAll;
eNR.Caption := IntToStr(dm.tbconta.RecordCount);
b1.setfocus;
end;


****{Agora vamos ao segundo problema}***********
Como deletar em cascata?

Pessoal agora que achei que estava pronta minha primeira S.Proc. Very Happy
Me deparei com o problema para deletar Sad

Isto ainda pq nem fiz o Update, espero que nao tenha porblemas tambem...hehehe

Bom,

Tenho uma tabela Meste e outra detalhe com um campo chamado sequencia que faz referencia, ai vou deletar em cascata, mais esta ocorrendo erro assim

"violation foreign key contraint FK_Debito_1 on table Debito foreign key references are present for the record"

Bom no delphi tenho um query para deletar assim
Código:
procedure TFConta.b5Click(Sender: TObject);
var
ok: boolean;
begin
if Tag = 1 then begin
beep;
ShowMessage('Este comando não está diponivel para este evento!');
Exit;
end;
if trim(edit1.text)='' then begin
showmessage('Selecione o codigo que vc deseja excluir');
end else
if application.messagebox(Pchar('Deseja Excluir este Lançamento:' + #13+'Mes do Lançamento: '+dm.qtbcontalanDataExtenso.AsString + #13+'Dia/Data do Lançamento: '+dm.qtbcontalanData.AsString +#13+'Valor do Lançamento:  '+dm.qtbcontalan.fieldbyname('valor').AsString+#13+'Histórico:  '+#13+ dm.qtbcontalanhistorico.AsString), Pchar('Excluir Dados'+Self.Caption), MB_ICONQUESTION
+ MB_YESNO) = IDYES then begin
try // começo do finally
  try //começo co except unie o laço
    with dm.qtbcontalan do
      begin
        close;
        sql.clear;
        sql.add('delete from tbconta'); //codigo SQL para deletar linha
        sql.add('where sequencia = '+quotedstr(edit1.text)+'');
        ExecSQL;
      end;
  except
      application.MessageBox('Erro na Gravação! Tente Novamente!','Aviso',mb_ok+mb_iconexclamation);
      ok:=false;
      editV; //procedure da unit funçoes

Antes quando nao usava S.Procedure funcionava, mais tambem estava um pouco diferente minha unit, mais agora nao funciona mais e mostra o erro acima:

Vou deixar postado minhas duas tabelas pra ver se tem haver
Tabela Mestre
Código:
SET SQL DIALECT 3;

SET NAMES ISO8859_1;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE TBCONTA (
    SEQUENCIA    INTEGER NOT NULL,
    CONTAD       VARCHAR(10),
    CONTAC       VARCHAR(10),
    VALOR        NUMERIC(15,2),
    DESCRICAO    BLOB SUB_TYPE 1 SEGMENT SIZE 80,
    DATA         DATE,
    VALORD       NUMERIC(15,2),
    VALORC       NUMERIC(15,2),
    DC           CHAR(1),
    CONTA        VARCHAR(10),
    DATAEXTENSO  VARCHAR(30),
    MES          VARCHAR(2),
    ANO          VARCHAR(4),
    MARCAR       CHAR(1),
    HISTORICO    VARCHAR(100) COLLATE PT_PT,
    NOMECD       VARCHAR(50),
    NOMECC       VARCHAR(50),
    NUMCONTAD    VARCHAR(10),
    NUMCONTAC    VARCHAR(10),
    NOMECONTA    VARCHAR(50),
    NUMCONTA     VARCHAR(10)
);




/******************************************************************************/
/***                              Primary Keys                              ***/
/******************************************************************************/

ALTER TABLE TBCONTA ADD CONSTRAINT PK_TBCONTA PRIMARY KEY (SEQUENCIA)
USING DESCENDING INDEX PK_TBCONTA;


/******************************************************************************/
/***                                Indices                                 ***/
/******************************************************************************/

CREATE DESCENDING INDEX IDXCONTA ON TBCONTA (SEQUENCIA);


/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/


SET TERM ^ ;


/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/



/* Trigger: AUTOINCRCONTA */
CREATE TRIGGER AUTOINCRCONTA FOR TBCONTA
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  if (new.sequencia is null) then
  select coalesce(max(sequencia),0)+1 from tbconta into new.sequencia;
end
^


/* Trigger: RETRCONTA */
CREATE TRIGGER RETRCONTA FOR TBCONTA
ACTIVE AFTER DELETE POSITION 0
AS
begin
 UPDATE tbconta SET SEQUENCIA = SEQUENCIA - 1
 WHERE SEQUENCIA > OLD.SEQUENCIA;
end
^


SET TERM ; ^


E a Tabela Detalhe
Código:
SET SQL DIALECT 3;

SET NAMES ISO8859_1;



/******************************************************************************/
/***                                 Tables                                 ***/
/******************************************************************************/



CREATE TABLE DEBITO (
    SEQUENCIA  INTEGER NOT NULL,
    CONTAD     VARCHAR(15),
    VALOR      NUMERIC(15,2),
    HISTORICO  VARCHAR(100),
    MES        VARCHAR(2),
    ANO        VARCHAR(4),
    DATA       DATE,
    CONTA      VARCHAR(15)
);




/******************************************************************************/
/***                              Foreign Keys                              ***/
/******************************************************************************/

ALTER TABLE DEBITO ADD CONSTRAINT FK_DEBITO_1 FOREIGN KEY (SEQUENCIA) REFERENCES TBCONTA (SEQUENCIA) ON DELETE CASCADE ON UPDATE CASCADE;


/******************************************************************************/
/***                                Indices                                 ***/
/******************************************************************************/

CREATE DESCENDING INDEX IDXDEBITO ON DEBITO (SEQUENCIA);


/******************************************************************************/
/***                                Triggers                                ***/
/******************************************************************************/


SET TERM ^ ;


/******************************************************************************/
/***                          Triggers for tables                           ***/
/******************************************************************************/



/* Trigger: TR_AUTOINC_DEBITO */
CREATE TRIGGER TR_AUTOINC_DEBITO FOR DEBITO
ACTIVE BEFORE INSERT POSITION 0
AS
begin
  /* Trigger text autoincremento */
  if (new.sequencia is null) then
  select coalesce(max(sequencia),0)+1 from debito into new.sequencia;
end
^


/* Trigger: TR_RETR_DEBITO */
CREATE TRIGGER TR_RETR_DEBITO FOR DEBITO
ACTIVE AFTER DELETE POSITION 0
AS
begin
  /* Trigger text retroceder debito*/
  UPDATE debito SET SEQUENCIA = SEQUENCIA - 1
  WHERE SEQUENCIA > OLD.SEQUENCIA;
end
^


SET TERM ; ^
Bom esta ai como criei as 2 tabelas

Desculpe pelo texto intenso mais foi a unica maneira que achei para mostrar se estou fazendo corretamente as tabelas

Agradeço a ajuda de todos
Adriano.
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qui Jan 11, 2007 6:49 pm    Assunto: Responder com Citação

Amigo, quanto ao primeiro problema, não entendi apenas pq você verifica se existe dados, depois de ter inserido. Digo isso pq, se inseriu, e não apareceu erro, existe pelo menos 1 registro na tabela.

Quanto ao segundo problema, é que vopcê criou uma trigger pra ser disparada depois que o registro é excluído. Note que , você está tentando alterar um registro, passando uma sequencia que pode ou não existir (não deve estar existindo). Como está sendo passado um valor inexistente para um campo com chave estrangeira, ele dá um erro de violação. O erro deve desaparecer se você remover essa trigger.
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qui Jan 11, 2007 7:02 pm    Assunto: Responder com Citação

thomazs escreveu:
Amigo, quanto ao primeiro problema, não entendi apenas pq você verifica se existe dados, depois de ter inserido. Digo isso pq, se inseriu, e não apareceu erro, existe pelo menos 1 registro na tabela.
Eh pq apareçe na dbgrid, se eu nao usar um select apareçe todos os dados e eu quero que apareça somente referente a condiçao where do select. Soh que achei muitos selects que usei para funciona, mais tudo bem esta funcionando.

Citação:
Quanto ao segundo problema, é que vopcê criou uma trigger pra ser disparada depois que o registro é excluído. Note que , você está tentando alterar um registro, passando uma sequencia que pode ou não existir (não deve estar existindo). Como está sendo passado um valor inexistente para um campo com chave estrangeira, ele dá um erro de violação. O erro deve desaparecer se você remover essa trigger.
Que trigger eh essa? Estou criando tantas que nem sei pq servem pelo menos a metade delas Very Happy

Eu posso criar tambem uma SProc para deletar todos cfe a chave primaria e estrangeira que eu fiz para referencias das tabelas?


Outra pergunta:
Eu li a respeito que o Firebird tem algumas limitaçoes tipo
Tamanho maximo do banco de dados ------> 7TB
Numero maximo de conexões ---------->1024
Entao a pergunta: O que vem a ser isso? Serah que o Firebird nao aguenta muitos dados em seu banco?
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree


Editado pela última vez por adriano_servitec em Qui Jan 11, 2007 7:14 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
thomazs
Moderador
Moderador


Registrado: Segunda-Feira, 1 de Março de 2004
Mensagens: 2835

MensagemEnviada: Qui Jan 11, 2007 7:11 pm    Assunto: Responder com Citação

A trigger é a TR_RETR_DEBITO
_________________
Suporte e Consultoria em Desenvolvimento de Sistemas
Bacharel em Sistemas de Informação
Especialista em Bancos de Dados
Desenvolvimento: Clipper, Delphi, PHP, Python/Django
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
adriano_servitec
Colaborador
Colaborador


Registrado: Sexta-Feira, 30 de Janeiro de 2004
Mensagens: 17618

MensagemEnviada: Qui Jan 11, 2007 7:17 pm    Assunto: Responder com Citação

Ei fiz essa trigger para retorceder o numero de sequencia quando eh deletado, assim acho que o campo sequencia fica organizado. Mai se nao pode vou deleta-la entao.

Eu posso criar tambem uma SProc para deletar todos cfe a chave primaria e estrangeira que eu fiz para referencias das tabelas?

Pq quero deletar em cascata assim

tabmestre.............................tabfilha
sequencia - integer----------->sequencia integer

assim que eu deletar na tabela meste a filha tambem eh deletada independente do numero da sequencia. Pois eh por ai que devo excluir
_________________
Jogo seu smartphone? Acesse o link e confira.
https://play.google.com/store/apps/details?id=br.com.couldsys.rockdrum
https://play.google.com/store/apps/details?id=br.com.couldsys.drumsetfree


Editado pela última vez por adriano_servitec em Qui Jan 11, 2007 7:25 pm, num total de 1 vez
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Banco de Dados Todos os horários são GMT - 3 Horas
Ir à página 1, 2  Próximo
Página 1 de 2

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB