none
SCOPE_IDENTITY() é seguro? RRS feed

  • Pergunta

  • Exemplo: Se eu quiser pegar o ID de uma linha que eu acabei de inserir usando o scope_identity() mas ao mesmo tempo estiver acontecendo uma outra inserção por outro usuário. Pode acontecer de pegar o ID errado?

    terça-feira, 15 de março de 2016 02:23

Respostas

  • Paulo,

    você pode usar o SCOPE_IDENTITY, pois pegará o identity do teu escopo. Seria um problema se você usasse IDENT_CURRENT ou @@IDENTITY.

    Veja o comentário a respeito no site da Microsoft:

    SCOPE_IDENTITY, IDENT_CURRENT, e @@IDENTITY são funções semelhantes porque retornam valores que são inseridos em colunas de identidade.

    IDENT_CURRENT não é limitado por escopo e sessão, mas a uma tabela especificada.IDENT_CURRENT retorna o valor gerado para uma tabela específica em qualquer sessão e escopo. IDENT_CURRENT (Transact-SQL).

    SCOPE_IDENTITY e @@IDENTITY retornam o último valor de identidade gerado em qualquer tabela da sessão atual. Entretanto, SCOPE_IDENTITY só retorna valores inseridos no escopo atual; @@IDENTITY não é limitada a um escopo específico.

    Por exemplo, há duas tabelas, T1 e T2, e um gatilho INSERT é definido em T1. Quando uma linha é inserida em T1, o gatilho é disparado e insere uma linha em T2. Esse cenário ilustra dois escopos: a inserção em T1 e a inserção em T2 pelo gatilho.

    Supondo que tanto T1 quanto T2 possuem colunas de identidade, @@IDENTITY e SCOPE_IDENTITY retornarão valores diferentes ao final de uma instrução INSERT em T1. @@IDENTITY retornará o último valor de coluna de identidade inserido em qualquer escopo na sessão atual. Este é o valor inserido em T2. SCOPE_IDENTITY() retornará o valor IDENTITY inserido em T1. Foi a última inserção que ocorreu no mesmo escopo. A função SCOPE_IDENTITY() retornará o valor nulo se for invocada antes que qualquer instrução INSERT em uma coluna de identidade ocorra no escopo.

    Instruções e transações com falha podem alterar a identidade atual de uma tabela e criar lacunas nos valores da coluna de identidade. O valor de identidade nunca é revertido, mesmo que a transação que tentou inserir o valor na tabela não seja confirmada. Por exemplo, se uma instrução INSERT falhar por causa de uma violação IGNORE_DUP_KEY, o valor de identidade atual para a tabela ainda será incrementado.

    SCOPE_IDENTITY (Transact-SQL)

    Att,


    Antero Marques



    terça-feira, 15 de março de 2016 02:43
  • Sim, a mesma regra. A questão dos gatilhos foi só pra ilustrar uma situação onde SCOPE_IDENTITY e @@IDENTITY trariam valores divergentes por suas características de abrangência.

    Att,


    Antero Marques

    • Marcado como Resposta PauloJoseBR terça-feira, 15 de março de 2016 03:46
    terça-feira, 15 de março de 2016 03:07

Todas as Respostas

  • Paulo,

    você pode usar o SCOPE_IDENTITY, pois pegará o identity do teu escopo. Seria um problema se você usasse IDENT_CURRENT ou @@IDENTITY.

    Veja o comentário a respeito no site da Microsoft:

    SCOPE_IDENTITY, IDENT_CURRENT, e @@IDENTITY são funções semelhantes porque retornam valores que são inseridos em colunas de identidade.

    IDENT_CURRENT não é limitado por escopo e sessão, mas a uma tabela especificada.IDENT_CURRENT retorna o valor gerado para uma tabela específica em qualquer sessão e escopo. IDENT_CURRENT (Transact-SQL).

    SCOPE_IDENTITY e @@IDENTITY retornam o último valor de identidade gerado em qualquer tabela da sessão atual. Entretanto, SCOPE_IDENTITY só retorna valores inseridos no escopo atual; @@IDENTITY não é limitada a um escopo específico.

    Por exemplo, há duas tabelas, T1 e T2, e um gatilho INSERT é definido em T1. Quando uma linha é inserida em T1, o gatilho é disparado e insere uma linha em T2. Esse cenário ilustra dois escopos: a inserção em T1 e a inserção em T2 pelo gatilho.

    Supondo que tanto T1 quanto T2 possuem colunas de identidade, @@IDENTITY e SCOPE_IDENTITY retornarão valores diferentes ao final de uma instrução INSERT em T1. @@IDENTITY retornará o último valor de coluna de identidade inserido em qualquer escopo na sessão atual. Este é o valor inserido em T2. SCOPE_IDENTITY() retornará o valor IDENTITY inserido em T1. Foi a última inserção que ocorreu no mesmo escopo. A função SCOPE_IDENTITY() retornará o valor nulo se for invocada antes que qualquer instrução INSERT em uma coluna de identidade ocorra no escopo.

    Instruções e transações com falha podem alterar a identidade atual de uma tabela e criar lacunas nos valores da coluna de identidade. O valor de identidade nunca é revertido, mesmo que a transação que tentou inserir o valor na tabela não seja confirmada. Por exemplo, se uma instrução INSERT falhar por causa de uma violação IGNORE_DUP_KEY, o valor de identidade atual para a tabela ainda será incrementado.

    SCOPE_IDENTITY (Transact-SQL)

    Att,


    Antero Marques



    terça-feira, 15 de março de 2016 02:43
  • Obrigado Antero, só que não estou usando gatilhos e sim procedimentos armazenados. A regra é a mesma?

    terça-feira, 15 de março de 2016 03:03
  • Sim, a mesma regra. A questão dos gatilhos foi só pra ilustrar uma situação onde SCOPE_IDENTITY e @@IDENTITY trariam valores divergentes por suas características de abrangência.

    Att,


    Antero Marques

    • Marcado como Resposta PauloJoseBR terça-feira, 15 de março de 2016 03:46
    terça-feira, 15 de março de 2016 03:07
  • Obrigado. 
    terça-feira, 15 de março de 2016 03:46