sql >> データベース >  >> RDS >> Sqlserver

SQL Server、データを失うことなくテーブルを作成した後に自動インクリメントを設定するにはどうすればよいですか?

    IDENTITYの変更 プロパティは実際にはメタデータのみの変更です。ただし、メタデータを直接更新するには、インスタンスをシングルユーザーモードで起動し、sys.syscolparsのいくつかの列をいじくり回す必要があります。 文書化されていない/サポートされていないため、私が推奨したり、追加の詳細を提供したりするものではありません。

    SQL Server 2012+でこの回答に出くわした人にとって、列の自動インクリメントのこの結果を達成する最も簡単な方法は、SEQUENCEを作成することです。 オブジェクトを作成し、next value for seqを設定します 列のデフォルトとして。

    または、以前のバージョン(2005以降)の場合、この接続アイテムに投稿された回避策は、ALTER TABLE...SWITCHを使用したデータ操作のサイズを必要とせずにこれを行う完全にサポートされた方法を示しています 。こちらのMSDNについてもブログに書いています。これを実現するためのコードはそれほど単純ではなく、制限がありますが、テーブルが変更されるなど、外部キー制約のターゲットにすることはできません。

    サンプルコード。

    identityのないテストテーブルを設定します 列。

    CREATE TABLE dbo.tblFoo 
    (
    bar INT PRIMARY KEY,
    filler CHAR(8000),
    filler2 CHAR(49)
    )
    
    
    INSERT INTO dbo.tblFoo (bar)
    SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT 0))
    FROM master..spt_values v1, master..spt_values v2
    

    identityを持つように変更します 列(多かれ少なかれ瞬時)。

    BEGIN TRY;
        BEGIN TRANSACTION;
    
        /*Using DBCC CHECKIDENT('dbo.tblFoo') is slow so use dynamic SQL to
          set the correct seed in the table definition instead*/
        DECLARE @TableScript nvarchar(max)
        SELECT @TableScript = 
        '
        CREATE TABLE dbo.Destination(
            bar INT IDENTITY(' + 
                         CAST(ISNULL(MAX(bar),0)+1 AS VARCHAR) + ',1)  PRIMARY KEY,
            filler CHAR(8000),
            filler2 CHAR(49)
            )
    
            ALTER TABLE dbo.tblFoo SWITCH TO dbo.Destination;
        '       
        FROM dbo.tblFoo
        WITH (TABLOCKX,HOLDLOCK)
    
        EXEC(@TableScript)
    
    
        DROP TABLE dbo.tblFoo;
    
        EXECUTE sp_rename N'dbo.Destination', N'tblFoo', 'OBJECT';
    
    
        COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        IF XACT_STATE() <> 0 ROLLBACK TRANSACTION;
        PRINT ERROR_MESSAGE();
    END CATCH;
    

    結果をテストします。

    INSERT INTO dbo.tblFoo (filler,filler2) 
    OUTPUT inserted.*
    VALUES ('foo','bar')
    

    与える

    bar         filler    filler2
    ----------- --------- ---------
    10001       foo       bar      
    

    クリーンアップ

    DROP TABLE dbo.tblFoo
    


    1. SQL Serverのdatetime2とsmalldatetime:違いは何ですか?

    2. PostgreSQLを使用して現在のデータベースのテーブルを一覧表示する方法

    3. Elasticsearchを使用したMicrosoftAccessデータの検索

    4. SQLエスケープを使用した動的mysqlクエリは、プリペアドステートメントと同じくらい安全ですか?