Usuário com melhor resposta
Como recuperar o ID de um registro que eu acabei de gerar por uma procedure?

Pergunta
-
O que eu preciso é o seguinte. Eu tenho um procedure que faz um insert e eu preciso recuperar por esta procedure o ID gerado. Como fazer isso ? Segue abaixo a minha procedure:
USE [iba_qa] GO /****** Object: StoredProcedure [dbo].[PRC_SPECIAL_LIST_ETAPA1] Script Date: 06/16/2012 17:17:30 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Guilherme Rodrigues Costa -- Create date: 16/06/2012 -- Description: Procedure responsável por incluir a etapa 1 do processo de inclusão de special list -- ============================================= ALTER PROCEDURE [dbo].[PRC_SPECIAL_LIST_ETAPA1] @ID INT = NULL, @NOME varchar(50) = '', @DESCRICAO varchar(50) = '', @URL varchar(100) = '' AS BEGIN IF @ID IS NULL BEGIN -- Insert statements for procedure here INSERT INTO [TB_SPECIAL_LISTS] ([NOME] ,[DESCRICAO] ,[URL]) VALUES (@NOME ,@DESCRICAO ,@URL) END ELSE BEGIN -- Insert statements for procedure here UPDATE [TB_SPECIAL_LISTS] SET [NOME] = @NOME ,[DESCRICAO] = @DESCRICAO ,[URL] = @URL WHERE ID = @ID END END GO
Guilherme Costa
Email: guilerme18@hotmail.comSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.
Respostas
-
Guilherme,
Caso seu campo seja IDENTITY, eu faria da seguinte forma:
USE [iba_qa] GO /****** Object: StoredProcedure [dbo].[PRC_SPECIAL_LIST_ETAPA1] Script Date: 06/16/2012 17:17:30 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Guilherme Rodrigues Costa -- Create date: 16/06/2012 -- Description: Procedure responsável por incluir a etapa 1 do processo de inclusão de special list -- ============================================= ALTER PROCEDURE [dbo].[PRC_SPECIAL_LIST_ETAPA1] @ID INT = NULL, @NOME varchar(50) = '', @DESCRICAO varchar(50) = '', @URL varchar(100) = '' AS BEGIN IF @ID IS NULL BEGIN -- Insert statements for procedure here INSERT INTO [TB_SPECIAL_LISTS] ([NOME] ,[DESCRICAO] ,[URL]) VALUES (@NOME ,@DESCRICAO ,@URL) END ELSE BEGIN -- Insert statements for procedure here UPDATE [TB_SPECIAL_LISTS] SET [NOME] = @NOME ,[DESCRICAO] = @DESCRICAO ,[URL] = @URL WHERE ID = @ID END SELECT ISNULL(@ID, SCOPE_IDENTITY()) AS 'IdRetorno' END GO
Essa linha inserida no fim da PROC, retornará o Id inserido ou que sofreu UPDATE (partindo de que vc sempre informará um Id quando quiser realizar uma atualização nos dados ).
[]'s
Philipe Souza
E-mail: Philipe.s.souza@hotmail.com- Sugerido como Resposta Roberto F FonsecaModerator segunda-feira, 18 de junho de 2012 02:07
- Marcado como Resposta Roberto F FonsecaModerator segunda-feira, 18 de junho de 2012 02:07
-
Meu professor de certificação falou para eu fazer utilizando o output ... ficou assim:
USE [iba_qa] GO /****** Object: StoredProcedure [dbo].[PRC_SPECIAL_LIST_ETAPA1] Script Date: 06/16/2012 17:37:46 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Guilherme Rodrigues Costa -- Create date: 16/06/2012 -- Description: Procedure responsável por incluir a etapa 1 do processo de inclusão de special list -- ============================================= ALTER PROCEDURE [dbo].[PRC_SPECIAL_LIST_ETAPA1] @ID INT = NULL, @NOME varchar(50) = '', @DESCRICAO varchar(50) = '', @URL varchar(100) = '' AS BEGIN IF @ID IS NULL BEGIN -- Insert statements for procedure here INSERT INTO [TB_SPECIAL_LISTS] ([NOME] ,[DESCRICAO] ,[URL]) OUTPUT INSERTED.id VALUES (@NOME ,@DESCRICAO ,@URL) END ELSE BEGIN -- Insert statements for procedure here UPDATE [TB_SPECIAL_LISTS] SET [NOME] = @NOME ,[DESCRICAO] = @DESCRICAO ,[URL] = @URL OUTPUT INSERTED.id WHERE ID = @ID END END GO
Funciou lindo..... acho que esta é a melhor solução.... valeu pela ajuda.
Guilherme Costa
Email: guilerme18@hotmail.comSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Editado Guilherme Costa - Campinas - SP sábado, 16 de junho de 2012 20:55 s
- Marcado como Resposta Guilherme Costa - Campinas - SP domingo, 17 de junho de 2012 18:14
Todas as Respostas
-
-
Guilherme,
Caso seu campo seja IDENTITY, eu faria da seguinte forma:
USE [iba_qa] GO /****** Object: StoredProcedure [dbo].[PRC_SPECIAL_LIST_ETAPA1] Script Date: 06/16/2012 17:17:30 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Guilherme Rodrigues Costa -- Create date: 16/06/2012 -- Description: Procedure responsável por incluir a etapa 1 do processo de inclusão de special list -- ============================================= ALTER PROCEDURE [dbo].[PRC_SPECIAL_LIST_ETAPA1] @ID INT = NULL, @NOME varchar(50) = '', @DESCRICAO varchar(50) = '', @URL varchar(100) = '' AS BEGIN IF @ID IS NULL BEGIN -- Insert statements for procedure here INSERT INTO [TB_SPECIAL_LISTS] ([NOME] ,[DESCRICAO] ,[URL]) VALUES (@NOME ,@DESCRICAO ,@URL) END ELSE BEGIN -- Insert statements for procedure here UPDATE [TB_SPECIAL_LISTS] SET [NOME] = @NOME ,[DESCRICAO] = @DESCRICAO ,[URL] = @URL WHERE ID = @ID END SELECT ISNULL(@ID, SCOPE_IDENTITY()) AS 'IdRetorno' END GO
Essa linha inserida no fim da PROC, retornará o Id inserido ou que sofreu UPDATE (partindo de que vc sempre informará um Id quando quiser realizar uma atualização nos dados ).
[]'s
Philipe Souza
E-mail: Philipe.s.souza@hotmail.com- Sugerido como Resposta Roberto F FonsecaModerator segunda-feira, 18 de junho de 2012 02:07
- Marcado como Resposta Roberto F FonsecaModerator segunda-feira, 18 de junho de 2012 02:07
-
Meu professor de certificação falou para eu fazer utilizando o output ... ficou assim:
USE [iba_qa] GO /****** Object: StoredProcedure [dbo].[PRC_SPECIAL_LIST_ETAPA1] Script Date: 06/16/2012 17:37:46 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO -- ============================================= -- Author: Guilherme Rodrigues Costa -- Create date: 16/06/2012 -- Description: Procedure responsável por incluir a etapa 1 do processo de inclusão de special list -- ============================================= ALTER PROCEDURE [dbo].[PRC_SPECIAL_LIST_ETAPA1] @ID INT = NULL, @NOME varchar(50) = '', @DESCRICAO varchar(50) = '', @URL varchar(100) = '' AS BEGIN IF @ID IS NULL BEGIN -- Insert statements for procedure here INSERT INTO [TB_SPECIAL_LISTS] ([NOME] ,[DESCRICAO] ,[URL]) OUTPUT INSERTED.id VALUES (@NOME ,@DESCRICAO ,@URL) END ELSE BEGIN -- Insert statements for procedure here UPDATE [TB_SPECIAL_LISTS] SET [NOME] = @NOME ,[DESCRICAO] = @DESCRICAO ,[URL] = @URL OUTPUT INSERTED.id WHERE ID = @ID END END GO
Funciou lindo..... acho que esta é a melhor solução.... valeu pela ajuda.
Guilherme Costa
Email: guilerme18@hotmail.comSe esta sugestão for útil, por favor, classifique-a como útil.
Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.- Editado Guilherme Costa - Campinas - SP sábado, 16 de junho de 2012 20:55 s
- Marcado como Resposta Guilherme Costa - Campinas - SP domingo, 17 de junho de 2012 18:14
-
-
Alexandre,
Apesar de ser um código válido. Não é recomendado que seja utilizada esta construção pois você poderá ter problemas com os IDs recuperados em caso de concorrencia na sua tabela.
Imagine a seguinte situação:
Usuário 1:
Inicia o Insert e finaliza o Insert (ID gerado mas ainda nao recuperado = 1)
Usuário 2 (ao mesmo tempo do usuário 1)
Inicia o Insert, depois de respeitar o bloqueio, finaliza o Insert Corretamente. (ID gerado mas ainda não recuperado = 2)
Usuário 1:
Após milésimos de segundo tenta recuperar o ID com a sua construção:
o retorno de @ID será? 2 (pois ele é o MAX(ID) da sua construção
Usuário 2:
Tenta recuperar o ID com a sua construção:
o retorno de @ID será 2 também.
Notou a falha que pode acontecer? Imagine que seja uma venda, você estará vendendo dois produtos para um mesmo cliente (neste caso o cliente 2)... Isso é uma falha que não pode acontecer nunca. Imagine que o cliente 1 deixe de fazer o pagamento.... Internamente você irá pesquisar e verificar que o cliente inadimplente é o cliente 2 ao invés do cliente 1. Agora imagine protestar o cliente 2... A dor de cabeça que vai ser....
Tente utilizar a sugestão do Guilherme, ou então a sugestão do Philipe para esses casos.
Att,
Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008
- Sugerido como Resposta Roberson Naves terça-feira, 3 de julho de 2012 20:23