`IDENTITY(seed, increment)` 是 SQL Server 表級屬性,非資料類型。深入理解其參數、限制與變更操作,能避免遷移、重構、資料修復時的常見坑。
IDENTITY [ ( seed , increment ) ]
CREATE TABLE WorkRoom (
WorkRoomID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
WorkRoomName VARCHAR(50) NULL,
TeacherName VARCHAR(10) NULL,
WorkRoomManager VARCHAR(10) NULL,
WorkRoomPlan VARCHAR(MAX) NULL,
Purl VARCHAR(50) NULL,
Remarks VARCHAR(MAX) NULL
);
增量一旦建立無法修改。若需變更增量,必須重建欄位。
-- 重置種子 (下一筆插入值)
DBCC CHECKIDENT ('WorkRoom', RESEED, 0); -- 下一筆為 1
DBCC CHECKIDENT ('WorkRoom', RESEED, 100); -- 下一筆為 101
鐵律:`ALTER TABLE ... ALTER COLUMN ...` 無法移除 IDENTITY。系統表 `sys.columns` 的 `is_identity` 位元不可直接清除 (舊版可透過系統表 Hack,極度不建議)。
-- ⚠️ 生產環境嚴禁,可能導致元資料損壞
EXEC sp_configure 'allow updates', 1; RECONFIGURE WITH OVERRIDE;
UPDATE syscolumns SET colstat = colstat & 0x0000
WHERE id = OBJECT_ID('表名') AND name = '欄位名';
EXEC sp_configure 'allow updates', 0; RECONFIGURE;
-- 以 zx_user.userid 為例
BEGIN TRANSACTION;
-- 1. 新增臨時欄位
ALTER TABLE zx_user ADD useridtmp INT NULL;
-- 2. 複製資料
UPDATE zx_user SET useridtmp = userid;
-- 3. 刪除 PK 約束 (必須先刪 PK 才能刪欄位)
-- 先查詢 PK 名稱
SELECT name FROM sysobjects WHERE xtype='PK' AND parent_obj=OBJECT_ID('zx_user');
-- 假設 PK 名為 pk_zx_user
ALTER TABLE zx_user DROP CONSTRAINT pk_zx_user;
-- 4. 刪除原身分欄位
ALTER TABLE zx_user DROP COLUMN userid;
-- 5. 新增無 IDENTITY 欄位
ALTER TABLE zx_user ADD userid INT NULL;
-- 6. 還原資料
UPDATE zx_user SET userid = useridtmp;
-- 7. 刪除臨時欄位
ALTER TABLE zx_user DROP COLUMN useridtmp;
-- 8. 設定 NOT NULL
ALTER TABLE zx_user ALTER COLUMN userid INT NOT NULL;
-- 9. 重建 PK
ALTER TABLE zx_user ADD CONSTRAINT pk_zx_user PRIMARY KEY (userid);
COMMIT;
-- 1. 複製結構與資料到新表 (不複製索引/約束/Identity)
SELECT * INTO zx_user_new FROM zx_user WHERE 1=0; -- 僅結構
-- 或帶資料
SELECT * INTO zx_user_new FROM zx_user;
-- 2. 新表 userid 現為普通 INT,確認無 Identity
-- 3. 建立索引、PK、FK、預設值等
-- 4. 交換表名
EXEC sp_rename 'zx_user', 'zx_user_old';
EXEC sp_rename 'zx_user_new', 'zx_user';
-- 5. 驗證後刪除舊表
`SELECT INTO` 不複製 Identity、索引、約束、觸發器、權限,適合「去 Identity」重建場景。大表比逐步 ALTER 快得多。
-- 所有 Identity 欄位
SELECT OBJECT_NAME(object_id) AS TableName, name AS ColumnName,
seed_value, increment_value, last_value
FROM sys.identity_columns;
-- 特定表
SELECT * FROM sys.identity_columns WHERE object_id = OBJECT_ID('WorkRoom');