Sqlserver
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Sqlserver

SQL Server, Làm thế nào để đặt tự động tăng sau khi tạo bảng mà không bị mất dữ liệu?

Thay đổi IDENTITY thuộc tính thực sự là một thay đổi chỉ siêu dữ liệu. Nhưng để cập nhật trực tiếp siêu dữ liệu yêu cầu bắt đầu phiên bản ở chế độ người dùng đơn lẻ và làm rối tung một số cột trong sys.syscolpars và không có giấy tờ / không được hỗ trợ và không phải là thứ tôi muốn giới thiệu hoặc sẽ cung cấp thêm bất kỳ chi tiết nào về.

Đối với những người bắt gặp câu trả lời này trên SQL Server 2012+, cách dễ nhất để đạt được kết quả này của cột tự động tăng dần sẽ là tạo SEQUENCE và đặt next value for seq làm cột mặc định.

Ngoài ra, hoặc đối với các phiên bản trước (từ năm 2005 trở đi), cách giải quyết được đăng trên mục kết nối này cho thấy một cách được hỗ trợ hoàn toàn để thực hiện việc này mà không cần kích thước hoạt động dữ liệu bằng cách sử dụng ALTER TABLE...SWITCH . Cũng được viết blog về MSDN tại đây. Mặc dù mã để đạt được điều này không đơn giản lắm và có những hạn chế - chẳng hạn như bảng được thay đổi không thể là mục tiêu của ràng buộc khóa ngoại.

Mã mẫu.

Thiết lập bảng kiểm tra không có identity cột.

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

Thay nó để có identity (ít nhiều tức thì).

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;

Kiểm tra kết quả.

Đã chèn
INSERT INTO dbo.tblFoo (filler,filler2) 
OUTPUT inserted.*
VALUES ('foo','bar')

Cho

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

Dọn dẹp

DROP TABLE dbo.tblFoo


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tìm ngày gần nhất trong SQL Server

  2. Sự khác biệt giữa việc sử dụng phép nối chéo và đặt dấu phẩy giữa hai bảng là gì?

  3. Cột được tính toán trong Mã EF Đầu tiên

  4. DATEFROMPARTS () Ví dụ trong SQL Server (T-SQL)

  5. Các trường hợp sử dụng để chọn CHAR qua VARCHAR trong SQL là gì?