Trigger para ajustar campo identity na virada de ano
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
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
Curtidas 0
Respostas
Marcus.magalhaes
08/11/2004
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,
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,
GOSTEI 0
Rounilo
08/11/2004
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
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
GOSTEI 0
Marcus.magalhaes
08/11/2004
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,
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,
GOSTEI 0
Rounilo
08/11/2004
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
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
GOSTEI 0
Marcus.magalhaes
08/11/2004
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,
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,
GOSTEI 0