PL/SQL ORACLE (trigger para comparar campos

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
Tosemsorte
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Dom, 20 Mar 2011 7:41 pm
Localização: são Paulo SP

Olá Boa noite,Sou estudante de Analise de sistemas e estou começando em Banco de dados.
Preciso criar uma trigger que compare 2 campos de uma mesma coluna e esta impeça que seja inserido 2 times iguais..

E outra que impeça que um jogador sem time cadastrado no campeonato participe de uma partida
O Segundo codigo consegui fazer

que e este:

Selecionar tudo

CREATE OR REPLACE TRIGGER valida_atuacao
BEFORE INSERT OR UPDATE ON jog_partida
FOR EACH ROW
DECLARE
mandante partida.sigla_time_mandante%TYPE;
desafiante partida.sigla_time_desafiante%TYPE;
time_jog jogador.sigla_time%TYPE;
BEGIN
SELECT sigla_time
	INTO time_jog
	FROM jogador
	WHERE num_incr_jog = :NEW.num_incr_jog;
SELECT sigla_time_mandante, sigla_time_desafiante
	INTO mandante, desafiante
	FROM partida
	WHERE num_par = :NEW.num_par;
IF time_jog
	NOT IN (mandante, desafiante) THEN
RAISE_APPLICATION_ERROR (-20005, 'Jogador não faz parte dos times participantes da partida!');
END IF;
END;
já O Codigo para comparar os times da partida roda mas não bloqueia que 2 times de siglas iguais sejam cadastrados.

Selecionar tudo

CREATE OR REPLACE TRIGGER compara_times
BEFORE INSERT OR UPDATE ON partida
FOR EACH ROW
DECLARE
mandante partida.sigla_time_mandante%TYPE;
desafiante partida.sigla_time_desafiante%TYPE;
BEGIN
IF (mandante=desafiante)OR(mandante=mandante)OR (desafiante=desafiante)
THEN
RAISE_APPLICATION_ERROR (204, 'você inseriu dois times iguais na partida!');
END IF;
END;
ishii
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 82
Registrado em: Ter, 28 Dez 2010 7:41 pm
Localização: São Paulo - SP

Olá,

Faltou informar quais são os valores do mandante e desafiante.

Selecionar tudo

CREATE OR REPLACE TRIGGER compara_times 
BEFORE INSERT OR UPDATE ON partida 
FOR EACH ROW 
BEGIN 
IF (:new.sigla_time_mandante=:new.sigla_time_desafiante)OR(:new.sigla_time_mandante=:new.sigla_time_mandante)OR (:new.sigla_time_desafiante=:new.sigla_time_desafiante) 
THEN 
RAISE_APPLICATION_ERROR (204, 'você inseriu dois times iguais na partida!'); 
END IF; 
END;
Como estou usando :new.coluna não preciso declarar a mesma...

[]s Ishii
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

Apenas um porém com relação a trigger postada pelo ishii,

O teste

Selecionar tudo

(:new.sigla_time_mandante=:new.sigla_time_mandante)OR (:new.sigla_time_desafiante=:new.sigla_time_desafiante) 
sempre vai ser verdadeiro, de certa forma é uma redundancia.
Tosemsorte
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Dom, 20 Mar 2011 7:41 pm
Localização: são Paulo SP

Havia feito tambem comparando a entrada de novos valores

assim como postado porem apresentou um erro...


Bom populei as tabelas com os valores desta forma:

SPO -- são paulo
COR -- CORINTHIANS
PAL -- PALMEIRAS


Esta seria a tabela partida
.....

Selecionar tudo

CREATE TABLE partida
(num_part NUMBER(10) PRIMARY KEY,
local_part VARCHAR2(100) NOT NULL,
dt_hr_part TIMESTAMP,
pub_totl_part NUMBER(10,2),
pub_pag_part NUMBER(10,2),
renda_partida NUMBER(10,2),
sigla_time_mandante CHAR(10),
sigla_time_desafiante CHAR(10),
pontuacao_mandante NUMBER(3),
pontuacao_desafiante NUMBER(3),
nome_camp_part VARCHAR2(30),
ano_camp_part DATE,
serie_camp_part CHAR(2) NOT NULL,
FOREIGN KEY (sigla_time_mandante) REFERENCES time(sigla_time),
FOREIGN KEY (sigla_time_desafiante) REFERENCES time(sigla_time),
FOREIGN KEY(nome_camp_part, ano_camp_part, serie_part) REFERENCES campeonato(nome_camp, ano_camp, serie_camp));
Tosemsorte
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Dom, 20 Mar 2011 7:41 pm
Localização: são Paulo SP

Apenas um porém com relação a trigger postada pelo ishii,

O teste

Selecionar tudo

(:new.sigla_time_mandante=:new.sigla_time_mandante)OR (:new.sigla_time_desafiante=:new.sigla_time_desafiante)
sempre vai ser verdadeiro, de certa forma é uma redundancia.

Como eu faço para dar um OK?

Poderia fazar da seguinte forma

SE
mandande =! desafiante --> Valida
Se não --> Erro....
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

A construção do ishii deve funcionar se retirar as cláusulas de redundancia:

Selecionar tudo

Create Or Replace Trigger compara_times
  Before Insert Or Update On partida
  For Each Row
Begin
  If :New.sigla_time_mandante = :New.sigla_time_desafiante Then
    raise_application_error(-20000, 'você inseriu dois times iguais na partida!');
  End If;
End;
Tosemsorte
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Dom, 20 Mar 2011 7:41 pm
Localização: são Paulo SP

Eu estava vindo responder justamente isto...
Havia editado desta forma...
Minha lógica estava errada também era so fazer o obvio quis inventar um pouco demais.

Bom o Código rodou e a restrição funcionou

so apresentou 2 erros a mais que foram estes

Selecionar tudo

ORA-20003: Os times inseridos na partida são iguais!
ORA-06512: em "SYSTEM.COMPARA_TIMES", line 4
ORA-04088: erro durante a execução do gatilho 'SYSTEM.COMPARA_TIMES'
gfkauer
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 389
Registrado em: Ter, 27 Jul 2010 1:34 pm
Localização: Sapiranga - RS
Contato:
Quem falou que programar era fácil??

Quanto mais dificil for a implementação mais valorizado seu trabalho será!

Acessem: www.gfkauer.com.br

Experimente alterar de -20000 para -20001 por exemplo...

Se não me engano a builtin Raise_application_error tem uma restição quanto a numeração do erro.

Espero que seja isto...
Tosemsorte
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 5
Registrado em: Dom, 20 Mar 2011 7:41 pm
Localização: são Paulo SP

continua dando este errinho, testei outra trigger e deu o mesmo erro, por hora vou deixar assim depois do uma buscada neste erro.


Por hora so mais uma duvida

estava com a seguinte procedure

Selecionar tudo

CREATE OR REPLACE PROCEDURE mostragols
	(vjogador IN jog_partida.num_incr_jog%TYPE)
IS
 CURSOR golspartida IS
	SELECT *
	  FROM jog_partida
	  WHERE num_incr_jog = vjogador;
 golsfinal golspartida%ROWTYPE;
 totalgols INTEGER := 0;
BEGIN
OPEN golspartida;
LOOP
  FETCH golspartida INTO golsfinal;
  EXIT WHEN golspartida%NOTFOUND;
  totalgols := totalgols + golsfinal.pontuacao_jog;
  DBMS_OUTPUT.PUT_LINE(TO_CHAR(golsfinal.num_incr_jog)||' assinalou '|| TO_CHAR(golsfinal.pontuacao_jog)||'gols, com total de' || TO_CHAR(totalgols));
END LOOP;
CLOSE golspartida;
END;
nela mostra os gols, agora preciso pegar estes gols e somar todos os gols de 1 time no campeonato e mostrar o saldo de gols.


Alguma sugestão de como eu posso seguir?
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 5 visitantes