 |
ActiveDelphi .: O site do programador Delphi! :.
|
Exibir mensagem anterior :: Exibir próxima mensagem |
Autor |
Mensagem |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Ter Jan 09, 2007 10:08 pm Assunto: Aprendendo a usar Trigger! |
|
|
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qua Jan 10, 2007 2:26 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qua Jan 10, 2007 2:43 pm Assunto: |
|
|
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qua Jan 10, 2007 3:19 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qua Jan 10, 2007 3:40 pm Assunto: |
|
|
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
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qua Jan 10, 2007 6:14 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qua Jan 10, 2007 10:18 pm Assunto: |
|
|
Obrigado Marcos Thomazs, agora acho que ja estou aprendendo um pouco mais sobre SProc e Trigger
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qui Jan 11, 2007 1:31 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qui Jan 11, 2007 2:12 pm Assunto: |
|
|
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qui Jan 11, 2007 6:26 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qui Jan 11, 2007 6:28 pm Assunto: |
|
|
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.
Me deparei com o problema para deletar
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qui Jan 11, 2007 6:49 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qui Jan 11, 2007 7:02 pm Assunto: |
|
|
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
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 |
|
 |
thomazs Moderador


Registrado: Segunda-Feira, 1 de Março de 2004 Mensagens: 2835
|
Enviada: Qui Jan 11, 2007 7:11 pm Assunto: |
|
|
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 |
|
 |
adriano_servitec Colaborador

Registrado: Sexta-Feira, 30 de Janeiro de 2004 Mensagens: 17618
|
Enviada: Qui Jan 11, 2007 7:17 pm Assunto: |
|
|
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 |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|