none
Trigger dando erro com função de calcular idade RRS feed

  • Pergunta

  • Preciso inserir um registro na tabela PessoaFisica

    CREATE TABLE PessoaFisica(
    	IdPessoa int NOT NULL primary key,
    	CPF bigint NOT NULL,
    	DataNascimento datetime NOT NULL 
    )
    ALTER TABLE PessoaFisica ADD CONSTRAINT Pessoa_PessoaFisica_fk FOREIGN KEY(IdPessoa)
    REFERENCES Pessoa(IdPessoa)
    

    Ao inserir a DataNascimento deve fazer usar uma trigger que chama a função que faz o calculo para saber se Idade é maior de 18, se sim o registro deve ser inserido,

    caso contrário desfazer insert

    A função acredito que esteja correta pois utilizei de exemplos aqui do forum

    ALTER FUNCTION FC_CALCULA_IDADE(
    	@Nascimento DATETIME,
    	@DataHoje DATETIME
    )
    RETURNS INT
    AS
    BEGIN
    	DECLARE @Idade INT
    
    	SET @Idade = YEAR(@DataHoje) - YEAR(@Nascimento) - 1
    
    	IF((MONTH(@DataHoje) = MONTH(@Nascimento) AND DAY(@DataHoje) >= DAY(@Nascimento))
    		OR MONTH(@DataHoje) > MONTH(@Nascimento))
    
    		SET @Idade = @Idade + 1
    
    	RETURN @IDADE
    END

    Trigger

    ALTER TRIGGER TG_VALIDA_IDADE ON
    PessoaFisica
    AFTER INSERT,UPDATE AS
    
    BEGIN
    	DECLARE @IdPessoa INT
    	DECLARE @CPF BIGINT
    	DECLARE @DataNascimento DATETIME
    	DECLARE @Idade INT
    	DECLARE @Hoje DATETIME
    
    	SET @Hoje = (SELECT GETDATE())
    
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM INSERTED
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM DELETED
    
    	SET @Idade = (SELECT dbo.FC_CALCULA_IDADE(@Hoje,@DataNascimento))		
    
    	IF(@Idade < 18)
    		BEGIN
    			PRINT 'IMPOSSÍVEL IDADE DEVE SER 18 OU MAIS'
    			ROLLBACK TRANSACTION
    		END
    	ELSE
    		BEGIN
    			INSERT INTO PessoaFisica(IdPessoa,CPF,DataNascimento)VALUES(@IdPessoa,@CPF,@DataNascimento)
    		END
    END

    O erro é que independente do Insert, da data de nascimento que eu coloque a TRIGGER bloqueia, não importa se for uma data que vai retornar a idade maior que 18

    Por favor ajude

    sábado, 14 de outubro de 2017 15:23

Respostas

  • Luciano,

    Este seu cenário esta muito similar a outro relacionado ao uso de Trigger para validação de CNPJ.

    Vou lhe fazer a mesma observação realizada anteriormente, porque você não utilize uma coluna com uma constraint do tipo check para validar a data de nascimento, ou então utilizar uma coluna computada com base em uma função.

    Veja se o exemplo abaixo lhe ajuda:

    -- Criando a Function F_CalcularDiferencaAnos --
    Create Function F_CalcularDiferencaAnos (@DataNascimento Date) 
    Returns Int 
    As 
    Begin
     Return (Select DATEDIFF(Year, @DataNascimento, GetDate()))
    End
    Go
    
    -- Criando a Tabela1 para Teste --
    Create Table Tabela1
    (Codigo Int,
     DataNascimento Date,
     DiferencaComputada As (dbo.F_CalcularDiferencaAnos(DataNascimento))) -- Criando uma coluna computada com a function --
    Go
    
    -- Inserindo os dados --
    Insert Into Tabela1 (Codigo, DataNascimento)
    Values (1,'1980-04-28'), (2,'1981-01-28')
    Go
    
    -- Validando o resultado --
    Select * from Tabela1
    Go


    Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    quarta-feira, 18 de outubro de 2017 22:31
  • Olá.

    duas coisas

    Se vc estiver usando uma trigger after, você não precisa fazer o insert novamente sendo na mesma tabela.

    Outra é que seus parametros na função q calcula a idade estão errados.

    Segue a trigger.

    alter TRIGGER TG_VALIDA_IDADE ON
    PessoaFisica
    after INSERT, update AS
    
    BEGIN
    	DECLARE @IdPessoa INT
    	DECLARE @CPF BIGINT
    	DECLARE @DataNascimento DATETIME
    	DECLARE @Idade INT
    	DECLARE @Hoje DATETIME
    
    	SET @Hoje = (SELECT GETDATE())
    
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM INSERTED
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM DELETED
    
    
    	SET @Idade = (SELECT dbo.FC_CALCULA_IDADE(@DataNascimento,@Hoje))		
    
    	IF(@Idade < 18)
    		BEGIN
    			PRINT 'IMPOSSÍVEL IDADE DEVE SER 18 OU MAIS'
    			ROLLBACK TRANSACTION
    		END
    	
    END
    

    Testes:

    insert into PessoaFisica (IdPessoa , cpf, DataNascimento) values (1,'123123123', '19850101')
    
    insert into PessoaFisica (IdPessoa , cpf, DataNascimento) values (2,'123123123', '20100101')
    

    Existem alguns artigos e tópicos no msdn falando sobre triggers e cuidados, sugiro a leitura.

    Abs


    Vinicius Fonseca - MCP | MCTS | MCDBA | MCITP | MCTS | MCT | ITIL Foundation - DGA SISTEMAS - Se minha resposta for útil, classifique-a. :)

    sábado, 14 de outubro de 2017 16:08

Todas as Respostas

  • Olá.

    duas coisas

    Se vc estiver usando uma trigger after, você não precisa fazer o insert novamente sendo na mesma tabela.

    Outra é que seus parametros na função q calcula a idade estão errados.

    Segue a trigger.

    alter TRIGGER TG_VALIDA_IDADE ON
    PessoaFisica
    after INSERT, update AS
    
    BEGIN
    	DECLARE @IdPessoa INT
    	DECLARE @CPF BIGINT
    	DECLARE @DataNascimento DATETIME
    	DECLARE @Idade INT
    	DECLARE @Hoje DATETIME
    
    	SET @Hoje = (SELECT GETDATE())
    
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM INSERTED
    	SELECT @IdPessoa = IdPessoa,@CPF = CPF,@DataNascimento = DataNascimento FROM DELETED
    
    
    	SET @Idade = (SELECT dbo.FC_CALCULA_IDADE(@DataNascimento,@Hoje))		
    
    	IF(@Idade < 18)
    		BEGIN
    			PRINT 'IMPOSSÍVEL IDADE DEVE SER 18 OU MAIS'
    			ROLLBACK TRANSACTION
    		END
    	
    END
    

    Testes:

    insert into PessoaFisica (IdPessoa , cpf, DataNascimento) values (1,'123123123', '19850101')
    
    insert into PessoaFisica (IdPessoa , cpf, DataNascimento) values (2,'123123123', '20100101')
    

    Existem alguns artigos e tópicos no msdn falando sobre triggers e cuidados, sugiro a leitura.

    Abs


    Vinicius Fonseca - MCP | MCTS | MCDBA | MCITP | MCTS | MCT | ITIL Foundation - DGA SISTEMAS - Se minha resposta for útil, classifique-a. :)

    sábado, 14 de outubro de 2017 16:08
  • Obrigado pela ajuda funcionou, mais eu juro que já tinha tentado dessa forma e estava dando erro.
    sábado, 14 de outubro de 2017 16:45
  • O Vinicius já respondeu como fazer a trigger funcionar, mas gostaria de te dar uma sugestão, você conhece constraints do tipo Check? Elas são muito mais simples do que triggers, possuem mais performance e muito mais fácil de se dar manutenção. Olha um exemplo de como a mesma regra implementada pela sua trigger ficaria:

    ALTER TABLE PessoaFisica ADD CONSTRAINT CK_Valida_Idade CHECK (DBO.FC_CALCULA_IDADE(DataNascimento ,GETDATE())>=18) 


    Ariel Goncalves Fernandez

    domingo, 15 de outubro de 2017 22:53
  • Deleted
    segunda-feira, 16 de outubro de 2017 08:37
  • Luciano,

    Este seu cenário esta muito similar a outro relacionado ao uso de Trigger para validação de CNPJ.

    Vou lhe fazer a mesma observação realizada anteriormente, porque você não utilize uma coluna com uma constraint do tipo check para validar a data de nascimento, ou então utilizar uma coluna computada com base em uma função.

    Veja se o exemplo abaixo lhe ajuda:

    -- Criando a Function F_CalcularDiferencaAnos --
    Create Function F_CalcularDiferencaAnos (@DataNascimento Date) 
    Returns Int 
    As 
    Begin
     Return (Select DATEDIFF(Year, @DataNascimento, GetDate()))
    End
    Go
    
    -- Criando a Tabela1 para Teste --
    Create Table Tabela1
    (Codigo Int,
     DataNascimento Date,
     DiferencaComputada As (dbo.F_CalcularDiferencaAnos(DataNascimento))) -- Criando uma coluna computada com a function --
    Go
    
    -- Inserindo os dados --
    Insert Into Tabela1 (Codigo, DataNascimento)
    Values (1,'1980-04-28'), (2,'1981-01-28')
    Go
    
    -- Validando o resultado --
    Select * from Tabela1
    Go


    Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    quarta-feira, 18 de outubro de 2017 22:31
  • Luciano,

    Este seu cenário esta muito similar a outro relacionado ao uso de Trigger para validação de CNPJ.

    Vou lhe fazer a mesma observação realizada anteriormente, porque você não utilize uma coluna com uma constraint do tipo check para validar a data de nascimento, ou então utilizar uma coluna computada com base em uma função.

    Veja se o exemplo abaixo lhe ajuda:

    -- Criando a Function F_CalcularDiferencaAnos --
    Create Function F_CalcularDiferencaAnos (@DataNascimento Date) 
    Returns Int 
    As 
    Begin
     Return (Select DATEDIFF(Year, @DataNascimento, GetDate()))
    End
    Go
    
    -- Criando a Tabela1 para Teste --
    Create Table Tabela1
    (Codigo Int,
     DataNascimento Date,
     DiferencaComputada As (dbo.F_CalcularDiferencaAnos(DataNascimento))) -- Criando uma coluna computada com a function --
    Go
    
    -- Inserindo os dados --
    Insert Into Tabela1 (Codigo, DataNascimento)
    Values (1,'1980-04-28'), (2,'1981-01-28')
    Go
    
    -- Validando o resultado --
    Select * from Tabela1
    Go


    Pedro Antonio Galvao Junior [MVP | MCC | MSTC | MIE | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitário | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    Essa á a melhor solução na minha opinião , como diz o Fabiano , Trigger is bad.

    Wesley Neves - Brasilia-DF

     
    https://wesleyneves.wordpress.com/
    MTA-SQL Server
    MTA- Web Development
    Analista Desenvolvedor.NET
    Pós-Graduando em Banco de Dados 
    "Se a resposta for útil ou ajudar ,não esqueça de marcar"





    • Editado Wesley Neves quinta-feira, 19 de outubro de 2017 10:40 complemento
    quinta-feira, 19 de outubro de 2017 10:40