none
Problema em retornar o ID(PK) da tabela RRS feed

  • Pergunta

  • Pessoal, preciso de ajuda

    Eu tenho essa tabela

    Tenho esse script de limpeza de base

    EXEC sp_MSForEachTable 'DISABLE TRIGGER ALL ON ?';
    GO
    EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL';
    GO
    EXEC sp_MSForEachTable 'IF OBJECTPROPERTY(object_id(''?''), ''TableHasForeignRef'') = 1 DELETE FROM ? else TRUNCATE TABLE ?';
    GO
    EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL';
    GO
    EXEC sp_MSForEachTable 'ENABLE TRIGGER ALL ON ?';
    GO
    EXEC sp_MSForEachTable 'IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1 DBCC CHECKIDENT (''?'', RESEED, 0)';


    Estou construindo esse script pra inserir na tabela

    USE DB_GrandesFaturadores
    GO
    
    BEGIN TRY
    	DECLARE @TempoInicio datetime, @TempoFim datetime
    
    	SET @TempoInicio = (SELECT GETDATE() TempoInicio)
    
    	BEGIN TRANSACTION ImportacaoCadastro
    
    		DECLARE @CnpjFornecedor VARCHAR(50),
    		@SiglaFornecedor  VARCHAR(50),
    		@Email  VARCHAR(50),
    		@Telefone  VARCHAR(50),
    		@UtilidadeFornecida  VARCHAR(50),
    		@contato  VARCHAR(50),
    		@DataInclusao  VARCHAR(50),
    		@LoginInclusao  VARCHAR(50),
    		@DataAtualizacao DATETIME,
    		@LoginAtualizacao  VARCHAR(50),
    		@DiaVencimento int,
    		@UnidadeMedida  VARCHAR(50),
    		@TokenAcesso  VARCHAR(50),
    		@IdFornecedorTipo int
    
    		DECLARE FornecedorAntigo CURSOR FOR
    		SELECT 
    		CnpjFornecedor,
    		SiglaFornecedor,
    		Email,
    		Telefone,
    		UtilidadeFornecida,
    		contato,
    		DataInclusao,
    		CASE WHEN LoginInclusao IS NULL THEN 'N/C' ELSE LoginInclusao END,
    		DataAtualizacao,
    		LoginAtualizacao,
    		DiaVencimento,
    		UnidadeMedida,
    		TokenAcesso
    		FROM SRVDES01.UTILIDADEPUBLICA_PRD_20151103.dbo.Fornecedor
    
    		OPEN FornecedorAntigo
    
    		FETCH NEXT FROM FornecedorAntigo INTO @CnpjFornecedor, @SiglaFornecedor, @Email, @Telefone, 
    		@UtilidadeFornecida, @contato, @DataInclusao, @LoginInclusao, @DataAtualizacao, @LoginAtualizacao, 
    		@DiaVencimento, @UnidadeMedida, @TokenAcesso
    
    	
    		WHILE @@FETCH_STATUS = 0
    		BEGIN
    		
    		    IF NOT EXISTS (SELECT UnidadeMedida FROM DB_GrandesFaturadores..FornecedorTipo WHERE UnidadeMedida = @UnidadeMedida)
    			BEGIN
    				INSERT INTO DB_GrandesFaturadores..FornecedorTipo (Nome, UnidadeMedida) 
    			    VALUES (@UtilidadeFornecida, @UnidadeMedida)
    
    				SET @IdFornecedorTipo = (SELECT IDENT_CURRENT ('DB_GrandesFaturadores.dbo.FornecedorTipo'));
    			END
    			ELSE
    			BEGIN
    				SET @IdFornecedorTipo = (SELECT Id FROM DB_GrandesFaturadores..FornecedorTipo WHERE UnidadeMedida = @UnidadeMedida)
    			END
    
    			INSERT INTO DB_GrandesFaturadores..Fornecedor (CnpjFornecedor, IdFornecedorTipo, Nome, NomeAbreviado, DiaVencimento, TokenAcesso, DataCriacao, LoginCriacao, DataAtualizacao, LoginAtualizacao) 
    			VALUES (@CnpjFornecedor, @IdFornecedorTipo, @SiglaFornecedor, 'N/C', @DiaVencimento, @TokenAcesso, @DataInclusao, @LoginInclusao, @DataAtualizacao, @LoginAtualizacao)
    
    			--==================================================================================================
    			--Problema para retorna o ID correto
    
    			declare @idfornecedorcontatoANTES int = (SELECT IDENT_CURRENT ('DB_GrandesFaturadores.dbo.FornecedorContato'))
    			print 'Id FornecedorContato ANTES: ' + CAST(@idfornecedorcontatoANTES as VARCHAR(50))
    
    			INSERT INTO DB_GrandesFaturadores..FornecedorContato (CnpjFornecedor, Nome, Email, Telefone) 
    			VALUES (@CnpjFornecedor, @contato, @Email, @Telefone)
    			print 'inserido FornecedorContato'
    
    			declare @idfornecedorcontatoDepois int = (SELECT IDENT_CURRENT ('DB_GrandesFaturadores.dbo.FornecedorContato'))
    			print 'IdFornecedorContato Depois: ' + CAST(@idfornecedorcontatoDepois as VARCHAR(50))
    			--==================================================================================================
    
    
    			FETCH NEXT FROM FornecedorAntigo INTO @CnpjFornecedor, @SiglaFornecedor, @Email, @Telefone, 
    			@UtilidadeFornecida, @contato, @DataInclusao, @LoginInclusao, @DataAtualizacao, @LoginAtualizacao, 
    			@DiaVencimento, @UnidadeMedida, @TokenAcesso
    		END
    
    		CLOSE FornecedorAntigo
    		DEALLOCATE FornecedorAntigo
    
    	COMMIT TRANSACTION ImportacaoCadastro
    
    	SET @TempoFim = (SELECT GETDATE() TempoFim)
    
    	SELECT @TempoInicio as Inicio, 
    	@TempoFim AS Fim, 
    	DateDiff(HOUR, @TempoInicio, @TempoFim) AS Hora,
    	DateDiff(MINUTE, @TempoInicio, @TempoFim) AS Minutos,
    	DateDiff(SECOND, @TempoInicio, @TempoFim) AS Segundos
    
    END TRY
    BEGIN CATCH
    	ROLLBACK TRANSACTION ImportacaoCadastro
    	
        DECLARE @ErrorMessage NVARCHAR(4000);
        DECLARE @ErrorSeverity inT;
        DECLARE @ErrorState inT;
    
        SELECT 
            @ErrorMessage = ERROR_MESSAGE(),
            @ErrorSeverity = ERROR_SEVERITY(),
            @ErrorState = ERROR_STATE();
    
        RAISERROR (@ErrorMessage,
                   @ErrorSeverity,
                   @ErrorState
                   );
    
    	IF (SELECT CURSOR_STATUS('global','FornecedorAntigo')) >= -1 --Cursor está aberto
    	BEGIN
    		CLOSE FornecedorAntigo
    		DEALLOCATE FornecedorAntigo
    		PRINT 'Cursor FornecedorAntigo Fechado'
    	END
    
    	SET @TempoFim = (SELECT GETDATE() TempoFim)
    
    	SELECT @TempoInicio , @TempoFim, DateDiff(MINUTE, @TempoInicio, @TempoFim) AS Minutos
    END CATCH


    O meu problema é o retorno do ID da tabela FornecedorContato, o primeiro insert está como zero

    Resultado

    Não sei se tem alguma coisa haver com com essa linha

    EXEC sp_MSForEachTable 'IF OBJECTPROPERTY(object_id(''?''), ''TableHasIdentity'') = 1 DBCC CHECKIDENT (''?'', RESEED, 0)';

    Quando eu coloco o RESEED igual a 1, a tabela FornecedorTipo do meu banco começa com 2

    Resultado

    Não sei o que pode estar de errado

    sexta-feira, 13 de novembro de 2015 20:01

Respostas

  • Rafael,

    O problema está no seu CHECKIDENT, como você mesmo identificou.

    Mas, o que acontece: (Fonte)

    "Current identity value is set to the new_reseed_value. If no rows have been inserted to the table since it was created, or all rows have been removed by using the TRUNCATE TABLE statement, the first row inserted after you run DBCC CHECKIDENT uses new_reseed_value as the identity. Otherwise, the next row inserted uses new_reseed_value + the current increment value."

    Ou seja... o DELETE e o TRUNCATE possuem comportamentos distintos quando é feito o DBCC CHECKIDENT

    Eu fiz uma simulação rápida aqui, veja:

    create table identity_del (a int identity (1,1))
    GO
    create table identity_trunc (a int identity (1,1))
    GO
    insert into identity_del default values
    go 10
    insert into identity_trunc default values
    go 10
    delete from identity_del
    go
    truncate table identity_trunc
    GO
    dbcc checkident (identity_del, reseed, 0)
    dbcc checkident (identity_trunc, reseed, 0)
    go
    select IDENT_CURRENT('identity_del'),IDENT_CURRENT('identity_trunc')
    GO
    select * from identity_del
    select * from identity_trunc
    drop table identity_trunc
    drop table identity_del

    []'s!


    /* Logan Destefani Merazzi - DBA | @LoganMerazzi | http://www.merazzi.eti.br
    Se a resposta for útil, vote nela. Se resolveu, marque-a como resposta. */

    segunda-feira, 16 de novembro de 2015 16:26

Todas as Respostas

  • Rafael,

    Sim tem tudo haver com a linha, o comando Reseed 0 esta reinicializando a contagem de valores da sua coluna Identity para Zero.

    Porque você esta utilizando esta linha de comando?


    Pedro Antonio Galvao Junior [MVP | MCC | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | Professor Universitario | SoroCodigos | @JuniorGalvaoMVP | http://pedrogalvaojunior.wordpress.com]

    sexta-feira, 13 de novembro de 2015 22:18
  • Fiz porque, após a limpeza da tabela X,  eu quero que o autoincremento começa-se denovo e não do ultimo ID

    Esse seria os passsos

    Insere registro 1, 2, 3, ......, 40

    Ultimo ID da tabela 40

    Limpeza da tabela e reset seed

    Insere os registro novamente 1, 2, 3, ......, 40


    sábado, 14 de novembro de 2015 10:16
  • Sim reseta pra zero e no insert o proximo ID serio 1 por causa identity increment e não o 0 novamente como mostrado no print do resultado da query
    segunda-feira, 16 de novembro de 2015 12:22
  • Rafael,

    O problema está no seu CHECKIDENT, como você mesmo identificou.

    Mas, o que acontece: (Fonte)

    "Current identity value is set to the new_reseed_value. If no rows have been inserted to the table since it was created, or all rows have been removed by using the TRUNCATE TABLE statement, the first row inserted after you run DBCC CHECKIDENT uses new_reseed_value as the identity. Otherwise, the next row inserted uses new_reseed_value + the current increment value."

    Ou seja... o DELETE e o TRUNCATE possuem comportamentos distintos quando é feito o DBCC CHECKIDENT

    Eu fiz uma simulação rápida aqui, veja:

    create table identity_del (a int identity (1,1))
    GO
    create table identity_trunc (a int identity (1,1))
    GO
    insert into identity_del default values
    go 10
    insert into identity_trunc default values
    go 10
    delete from identity_del
    go
    truncate table identity_trunc
    GO
    dbcc checkident (identity_del, reseed, 0)
    dbcc checkident (identity_trunc, reseed, 0)
    go
    select IDENT_CURRENT('identity_del'),IDENT_CURRENT('identity_trunc')
    GO
    select * from identity_del
    select * from identity_trunc
    drop table identity_trunc
    drop table identity_del

    []'s!


    /* Logan Destefani Merazzi - DBA | @LoganMerazzi | http://www.merazzi.eti.br
    Se a resposta for útil, vote nela. Se resolveu, marque-a como resposta. */

    segunda-feira, 16 de novembro de 2015 16:26
  • Logan

    Obrigado pela ajuda, funcionou corretamente, realmente não tinha prestado atenção no uso correto do dbcc checkident junto com delete e truncate

    Abraços


    segunda-feira, 16 de novembro de 2015 18:10