Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Vitor Thomaz Alves

Trigger Chave Composta

Recommended Posts

Buenasgalera, estou com a ideia de montar um sistema para controle de chamados de helpdesk, a lógica seria a seguinte:

O Analista abre um chamado X, este chamado pode ter diversos tramites, ou seja, X.1/X.2/X.3... assim vai. Para montar isso pensei em seguintes tabelas:


create table func (
cp_codfun int NOT NULL constraint pk_func primary key,
cp_nomfun varchar(50) NOT NULL,
cp_email varchar(50) NULL
)

create table cham (
cp_codcham int not null identity (1,1) constraint pk_cham primary key,
cp_datini date not null,
cp_codfun int not null constraint fk_cham_func foreign key references func(cp_codfun),
cp_nomcli varchar(50) not null,
cp_nomcont varchar (30) not null,
cp_desprob text not null,
cp_status varchar(10) not null constraint ck_status check (cp_status in ('aberto','fechado','aguardando'))
)

create table tram (
cp_codtra int not null constraint pk_tram primary key,
cp_numtra int not null,
cp_codcall int not null constraint fk_tram_cham foreign key references cham(cp_codcham),
cp_dattra date not null
)

A tabela de tramites, teria ligação com a tabela de chamados. A numeração do tramite tem que ser zerada sempre que mudar a numeração do chamado, perguntando em um lugar e outro me disseram que isso deve ser feito por uma trigger, porém, não sei nada sobre triggers.


Procurando e xeretando acabei chegando a isso aqui:

DROP TRIGGER IF EXISTS `HISCHM`;
DELIMITER //
CREATE TRIGGER `HISCHM` BEFORE INSERT ON `tram`
 FOR EACH ROW BEGIN
declare numero int default 0;
 Set numero = (select max(cp_numtra) From tram where cp_codcall = new.cp_codcall);
   if ((numero <= 0) or (numero is null))then
      set numero = 1;
   else
      set numero = numero + 1;
   end if;
   set new.cp_numtra = numero;
END
//
DELIMITER;

 

Mas não está funfando e não estou conseguindo descobrir o que pode ser?

Alguém tem uma luz divida de sabedoria?

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

Não conheço detalhes da síntaxe Sql Server mas a lógica me parece correta, qual o erro que ocorre ?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa, belezinha ou nem tanto Motta?

 

Então tinha muita coisa errada, a trigger que tinhamos encontrado era para MySQL, dai ela foi 'exportada' para SQLServer (descobrimos que isso não presta) e veio muita coisa errada!

 

Tem um camarada aqui no trampo que manja das @#$%$#@ e deu uma mão aqui, dai o barato ficou assim e funfou ó:

 

USE help
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'HISCHM' AND type = 'TR')
   DROP TRIGGER HISCHM
GO
CREATE TRIGGER HISCHM
ON tram 
FOR INSERT
AS
declare @numero int

select @numero = max(cp_numtra) From tram where cp_codcall = (select i.cp_codcall from inserted i)

  if ((@numero <= 0) or (@numero is null))
	  begin
		 set @numero = 1
	  end
  else
	  begin
		set @numero = @numero + 1
	  end

Agradeço pela ajuda e pela visualização da galera ai! Tá resolvido!

 

Abraços

Compartilhar este post


Link para o post
Compartilhar em outros sites

no luga de

select @numero = max(cp_numtra) From tram where cp_codcall = (select i.cp_codcall from inserted i)

 

faz um join para não ter problema de performance ou lock de tabela.

 

[]´s

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde A.Jr, como seria a ideia deste Join?

 

Desculpe a ignorância, meu conhecimento é limitado! *rs*

 

Sem problemas, como eu digo, é melhor perguntar no fórum do que pro chefe rs

 

Quando vc faz um subselect:

select @numero = max(cp_numtra) From tram where cp_codcall = (select i.cp_codcall from inserted i)

Ele vai listar todo o seu inserted para checar se tem algum registro igual, no seu caso, o negrito acima.

Eu mudaria para

select @numero = max(tram.cpnumtra) from tram inner join inserted on tram.cpcodcall = inserted.cpcodcall

 

deste modo quando um registro satisfazer a condição do JOIN (em negrito) ele já retorna resultado.

 

Em um volume pqno de dados, pode ser imperceptível a diferença, mas eu trabalho com volume de milhões de registros e cada segundo é valioso :p

Compartilhar este post


Link para o post
Compartilhar em outros sites

Entendi, no caso inicialmente (e creio que por um bom tempo) isso não seria problema, pois trata-se de certa de 1200 chamados/mês isso no ano daria 14400, mas como se diz:

 

"Tudo que faz fica feito!"

 

Então, vamos fazer direito!

 

Obrigado pela ajuda! =)

Compartilhar este post


Link para o post
Compartilhar em outros sites

---

 

Pessoal, abaixo segue a trigger correta:

 

USE help
IF EXISTS (SELECT name FROM sysobjects
      WHERE name = 'HISCHM' AND type = 'TR')
   DROP TRIGGER HISCHM
GO
CREATE TRIGGER HISCHM ON [dbo].[tram]instead OF INSERT AS
BEGIN
DECLARE @numero int

 select @numero = max(tram.cp_numtra) from tram inner join inserted on tram.cp_codcall = inserted.cp_codcall
  if ((@numero <= 0) or (@numero is null))
   begin
   set @numero = 1
   end
  else
   begin
  set @numero = @numero + 1
   end
	INSERT INTO tram (cp_codcall,cp_dattra,cp_numtra,cp_tram) 
	SELECT cp_codcall,cp_dattra,@numero,cp_tram FROM inserted;   
   end

Abraços.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.