Sql server DBCC命令在过程中不起作用

Sql server DBCC命令在过程中不起作用,sql-server,tsql,stored-procedures,dbcc,Sql Server,Tsql,Stored Procedures,Dbcc,我有以下疑问。从逻辑上讲,对于表dbo.Sales,过程usp_mytran应该将标识重新设定为1。但是最后一个查询返回不同的Max_ID_值和Current_Seed_值。有人能解释一下为什么DBCC命令在过程中不起作用吗 USE tempdb -- Create table CREATE TABLE dbo.Sales (ID INT IDENTITY(1,1), Address VARCHAR(200)) GO -- Procedure to Populate data int

我有以下疑问。从逻辑上讲,对于表dbo.Sales,过程usp_mytran应该将标识重新设定为1。但是最后一个查询返回不同的Max_ID_值和Current_Seed_值。有人能解释一下为什么DBCC命令在过程中不起作用吗

USE tempdb

--  Create table 
CREATE  TABLE dbo.Sales
(ID INT IDENTITY(1,1), Address VARCHAR(200))
GO

--  Procedure to Populate data into dbo.Sales
CREATE PROCEDURE usp_mytran 
AS
BEGIN
BEGIN TRANSACTION
    INSERT dbo.Sales
            ( Address )
    VALUES  ( 'Dwarka, Delhi' );

    --  Delete it for some reason
    DELETE FROM dbo.Sales;

    --  Code to check max ID value, and verify it again IDENTITY SEED
    DECLARE @MaxValue INT = (SELECT ISNULL(MAX(ID),1) FROM dbo.Sales)
    IF @MaxValue IS NOT NULL AND @MaxValue <> IDENT_CURRENT('dbo.Sales')
        DBCC CHECKIDENT ( 'tempdb.dbo.Sales', RESEED, @MaxValue );
ROLLBACK TRANSACTION
END

--  Ideally, this should RESEED the Identity of dbo.Sales table.
EXEC usp_mytran

--  Max_ID_Value & Current_Seed_Value should be same
SELECT ISNULL(MAX(ID),1) AS Max_ID_Value, IDENT_CURRENT('dbo.Sales') AS Current_Seed_Value FROM dbo.Sales

实际上,它在存储过程中按预期工作:Rollback tran将回滚checkident值——这就是代码中发生的情况

--  Procedure to Populate data into dbo.Sales
alter PROCEDURE usp_mytran 
AS
BEGIN
    BEGIN TRANSACTION
    INSERT dbo.Sales
            ( Address )
    VALUES  ( 'Dwarka, Delhi' );

    --  Delete it for some reason
    DELETE FROM dbo.Sales;

    --  Code to check max ID value, and verify it again IDENTITY SEED
    DECLARE @MaxValue INT = (SELECT ISNULL(MAX(ID),1) FROM dbo.Sales)
    IF @MaxValue IS NOT NULL AND @MaxValue <> IDENT_CURRENT('test.dbo.Sales')
        DBCC CHECKIDENT ( 'test.dbo.Sales', RESEED, @MaxValue );
    ROLLBACK TRANSACTION
END
您将看到CheckIdentit不会重置

如果我们删除该事务,则CHECKIDENT将重新设置为1

评论交易如下

--  Procedure to Populate data into dbo.Sales
alter PROCEDURE usp_mytran 
AS
BEGIN
    --BEGIN TRANSACTION
    INSERT dbo.Sales
            ( Address )
    VALUES  ( 'Dwarka, Delhi' );

    --  Delete it for some reason
    DELETE FROM dbo.Sales;

    --  Code to check max ID value, and verify it again IDENTITY SEED
    DECLARE @MaxValue INT = (SELECT ISNULL(MAX(ID),1) FROM dbo.Sales)
    IF @MaxValue IS NOT NULL AND @MaxValue <> IDENT_CURRENT('test.dbo.Sales')
        DBCC CHECKIDENT ( 'test.dbo.Sales', RESEED, @MaxValue );
    --ROLLBACK TRANSACTION
END
您将看到重新设定种子的值为“1”

检查下面的例子以及


很抱歉回答我自己的问题。正如@Kannan Kandasamy所指出的,回滚事务代码正在还原DBCC CHECKIDENT完成的工作。因此,为了使其正常工作,我创建了一个名为Reseed_Sales的作业,其中包含表dbo.Sales的Reseed Identity代码。以下是程序usp_mytran的最终查询


请多次执行usp_mytran过程,以注意Max_ID_Value和Current_Seed_Value的值之间的差异。我不知道您试图实现什么,但使用identity看起来不是正确的解决方案。您的代码在并发状态下存在各种问题。您好@MartinSmith,请检查问题。要求是,如果TRY块失败,则在CATCH块中重新设定标识值的种子,并回滚事务。所以这就是我试图通过保持回滚事务并在其中使用sql代理作业重新设置标识种子来实现的。如果您想要一个没有间隙的列,则标识不是该作业的正确工具。当您必须在一个简单的CRUD过程中执行诸如生成SQL代理作业之类的疯狂操作时,您应该意识到这一点。在并发模式下,您肯定会发现您的方法无论如何都不起作用。
--  Procedure to Populate data into dbo.Sales
alter PROCEDURE usp_mytran 
AS
BEGIN
    --BEGIN TRANSACTION
    INSERT dbo.Sales
            ( Address )
    VALUES  ( 'Dwarka, Delhi' );

    --  Delete it for some reason
    DELETE FROM dbo.Sales;

    --  Code to check max ID value, and verify it again IDENTITY SEED
    DECLARE @MaxValue INT = (SELECT ISNULL(MAX(ID),1) FROM dbo.Sales)
    IF @MaxValue IS NOT NULL AND @MaxValue <> IDENT_CURRENT('test.dbo.Sales')
        DBCC CHECKIDENT ( 'test.dbo.Sales', RESEED, @MaxValue );
    --ROLLBACK TRANSACTION
END
select IDENT_CURRENT('test.dbo.Sales')
--  Procedure to Populate data into dbo.Sales
ALTER PROCEDURE usp_mytran 
AS
BEGIN
BEGIN TRANSACTION
    INSERT dbo.Sales
            ( Address )
    VALUES  ( 'Dwarka, Delhi' );

    --  Delete it for some reason
    DELETE FROM dbo.Sales;

    --  Code to check max ID value, and verify it again IDENTITY SEED
    DECLARE @MaxValue INT = (SELECT ISNULL(MAX(ID),1) FROM dbo.Sales)
    IF @MaxValue IS NOT NULL AND @MaxValue <> IDENT_CURRENT('dbo.Sales')
        EXEC msdb..sp_start_job @job_name = 'Reseed_Sales'
ROLLBACK TRANSACTION
END