Trigger para ajustar campo identity na virada de ano

08/11/2004

0

Senhores tenho uma tabela de nome CERTSTOP com um campo
definido como :
codigo integer identity(2004000,1) not null

e pretendo criar um Trigger para, quando da virada do ano, setar o identity para 2005000,1.

Estou tentando com a codificação abaixo e estah dando erro.
Qual eh o erro ?
Poderei fazer de outra forma ??

***********************************
Create TRIGGER TRIG_CERTSTOP
ON CERTSTOP
FOR INSERT
AS
SELECT IDENT_CURRENT(´CERTSTOP´)
IF (DATEPART(YYYY,GETDATE()) >
IDENT_CURRENT
BEGIN
DBCC CHECKIDENT(´CERTSTOP´,RESEED,2005000)
END
*************************************************

Melhor seria se pudesse colocar o novo ano obtido na função datepar
acrescentado de + ´000´.

Agradeço sugestões.
Rounilo


Rounilo

Rounilo

Responder

Posts

09/11/2004

Marcus.magalhaes

Bom dia Rounilo.

Cara, criar uma trigger para fazer isso não acho uma boa idéia porque vc irá causar um erro de duplicate key. pq a cada insert seu ponteiro será setado para o mesmo valor inicial

Acredito q a melhor saida seja ou vc rodar o DBCC na mão no dia 31/12 qdo vc souber q ninguém mais vai ser cadastrado ou efetuar esta execução via job schedulado para às 12:00AM do dia 01/01/2005.

Att,


Responder

10/11/2004

Rounilo

Marcus, vou considear suas duas sugestões. Entretanto o problema é que terei que ter esta preocupação todo final de ano.

Uma coisa que não entendi na sua resposta foi a suposta ocorrência de duplicidade de chave. Penso que o que o levou a supor duplicidade foi o fato não ter informado que o número de inclusões, de novos registros, será bem menor do que 999 inclusões; o que sempre fará com que os quatros primeiros dígitos não sejam alterados, representando portanto, o ano.

O que pretendo é incluir no corpo da trigger, uma consulta para obter, da data do dia (GETDATE) o campo ano (yyyy) e acrescentar a este ´000´ e comparar este valor com o campo identity.
O que vai ocorrer no dia a dia:
- Imaginemos que fosse feita uma inclusão hoje e o valor do identity fosse 2004125.
Este valor do identity (2004125) seria comparado com o obtido na getdate acrescentado de 000 que seria ´2004000´. Por ser MAIOR não seria executado o comando DBCC, fazendo com que o sistema fizesse o incremento normal do identity para 2004126. OK ?

- Imaginemos agora um insert feito no dia 01/01/2005 com o valor do identity sendo, por exemplo, 2004789.

O valor que obteria pela funcão getdate e acrescido dos tres zeros seria 2005000, que comparado com 2004789 do identity, resulatia em MENOR. Por ser MENOR seria executado o comando DBCC, alterando o Identity para ´2005001,1´.
Nas próximas inclusões o resultado da comparação seria sempre MAIOR, OK ?

A lógica me parece correta. O que não sei é como codifica-la em uma trigger.

Peço que vc analise este novo comentário.
Obrigado
Rounilo


Responder

10/11/2004

Marcus.magalhaes

Bom dia.

Ok, entendi o ponto da duplicidade, até aí blz.

Mas a lógica do getdate() pegando o ano + ´000´ poderia ser montanda num job q seria agendado para rodar somente em 1o. de janeiro e não a cada insert, o q causaria lentidão no insert. Overhead desnecessário.

Att,


Responder

10/11/2004

Rounilo

Marcus, concordo sua sugestão. Realmente nos parece melhor por ocasionar menor overhead no sistema.

Marcus, senão for pedir demais gostaria que vc me esclarecesse dois pontos:
Posso eu, responsável pela aplicação e pela Base de dados envolvida, implementar este JOB ou terá que ser implementada por um DBA?

Qual o erro na codificação da Trigger ? Será bom conhece-lo para evitar futuros problemas.

Sds


Responder

10/11/2004

Marcus.magalhaes

Boa tarde Rounilo.

Respondendo às suas questões :

1) O ideal é que um DBA faça todos os agendamentos, pois só ele pode ter a senha de [b:88414a6946]sa[/b:88414a6946], ou pelo menos deveria. E em ambientes de produção, apesar do DBA não ser o dono da base, ele é a pessoa responsável pela sua manutenção/administração.

2) Aqui está seu código corrigido :
[color=red:88414a6946]Create Table CERTSTOP
(
Col1IntIdentity(1, 1)NOT NULL,
Col2VarChar(10)NOT NULL
)
GO

Create TRIGGER TRIG_CERTSTOP ON CERTSTOP FOR INSERT
AS
Begin
IF Convert(Int, Convert(VarChar, DATEPART(YYYY,GETDATE())) + ´000´) > IDENT_CURRENT(´CERTSTOP´)
BEGIN
DBCC CHECKIDENT(´CERTSTOP´,RESEED,2005000)
END
End
GO

DBCC CHECKIDENT(´CERTSTOP´,RESEED,2003000)
GO

Insert Into certstop (col2) values (´teste1´)
Insert Into certstop (col2) values (´teste2´)
Insert Into certstop (col2) values (´teste3´)
Insert Into certstop (col2) values (´teste4´)

Select *
From certstop

Drop table CERTSTOP
GO[/color:88414a6946]

Outra coisa, como isto seria uma Trigger e este tipo de objeto age somente depois da ação ter sido efetivada, o 1o. registro que fizesse com que seu if fosse verdadeiro não seria afetado, portanto não teria um novo código. Observe isso no exemple que estou te mandando acima, a primeira linha NUNCA será 2004xxx.

PS.: eu setei para 2003000 o identity inicial para que o teste funcionasse.

Att,


Responder

Assista grátis a nossa aula inaugural

Assitir aula

Saiba por que programar é uma questão de
sobrevivência e como aprender sem riscos

Assistir agora

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar