|
||
|
|
Conheça também: Onmasters . Ofertas . Divulgue! . Vai.la . Geraboleto . Baixa.la . Assista.la . Joga.la
» Início » Desenvolvimento » Banco de dados e SQL » SQL Server: Geração de seqüenciais de forma automática
--> |
|
Avaliação:
![]() ![]() ![]() ![]() | Publicado em: 20/09/2007SQL Server: Geração de seqüenciais de forma automática
DivergênciasPara mostrar possíveis divergências entre as funções para recuperar o Identity, será utilizada uma situação fictícia de um sistema contábil. Esse sistema possui duas tabelas. A primeira tabela é a que possui os lançamentos contábeis e a segunda tabela é uma auditoria de algumas operações realizadas sobre os lançamentos. Toda vez que um lançamento é inserido ou excluído, um registro é gravado automaticamente (através de uma trigger) na tabela de auditoria e ambas as tabelas possuem um campo Identity. Certamente uma auditoria efetiva não iria usar mecanismos tão simples, mas a idéia é apenas exemplificar algumas divergências e não construir um poderoso sistema de auditoria ou exemplificar como as triggers funcionam. -- Criação das tabelas CREATE TABLE tblAuditoriaContabil ( -- Cria uma Trigger para gravação automática de auditoria -- Grava o registro deletado se houver END Inicialmente será realizado o cadastro de um lançamento contábil na tabela de lançamentos. Após a realização desse lançamento, automaticamente um registro é gerado na tabela de auditoria informando que um registro foi inserido. Como as duas tabelas tem campos Identity e é o primeiro registro em ambas as tabelas, o ID retornado será igual a um. Nesse primeiro momento, as funções @@identity e Scope_Identity() retornam o mesmo resultado conforme demonstrado abaixo: -- Faz um novo lançamento -- Captura o valor de @@identity e Scope_Identity() -- Verifica os IDs das tabelas Posteriormente o lançamento (ID 1) é excluído. Essa ação provocará uma entrada na tabela de auditoria que agora possui dois registros (um com ID 1 e outro com ID 2) referentes às operações de INSERT e DELETE. O próximo registro da tabela de lançamentos deve ter ID igual a 2 (o ID foi eliminado e não é reaproveitado) e o próximo registro na tabela de auditoria deve ter ID igual a 3. O script abaixo mostra essas ações: -- Efetua um DELETE do lancamento -- Verifica os IDs das tabelas -- Faz um novo lançamento Da primeira vez, o Identity era igual a 1, pois ambas as tabelas estavam vazias e o ID era o mesmo. Após a realização do segundo INSERT, como saber de qual tabela o Identity será retornado ? Essa é justamente a diferença entre as funções @@identity e Scope_Identity. O @@identity irá retornar o último Identity gerado pela conexão que no caso refere-se a tabela de auditoria (ID = 3). O Scope_Identity() irá retornar o último Identity gerado pela conexão, mas no caso é considerado o escopo. O escopo que disparou a ação foi o INSERT na tabela de lançamentos, o ID considerado por essa função refere-se a essa tabela. Isso pode ser verificado através dos comandos abaixo: -- Captura o valor de @@identity e Scope_Identity() -- Verifica os IDs das tabelas Na grande maioria das situações, o escopo é único e nesse caso as funções @@identity e Scope_Identity() trazem resultados idênticos. No entanto, se mais de um escopo estiver envolvido, é preciso saber quando utilizar cada uma para evitar retornar valores errados. Uma possível solução para evitar esse tipo de problema é a utilização da função IDENT_CURRENT. Como essa função recebe o nome da tabela como argumento, ela poderia auxiliar independentemente da quantidade de escopos utilizados. De fato isso parece ser factível. O problema é que se muitos usuários acessarem o sistema simultaneamente (grande concorrência), pode haver um atraso entre a ação que gera um novo Identity e a recuperação através da função IDENT_CURRENT. As funções @@identity e Scope_Identity() levam em conta o contexto que gerou esses valores e são imunes a problemas de grandes concorrências. ![]() |
|
|