1. 程式人生 > >SQL Server解惑——標識列的限制和跳號現象

SQL Server解惑——標識列的限制和跳號現象

 

1:每個表只能建立一個標識列。

 

如下測試所示,如果表中有一個標識列,新增一個標識列就會遇到錯誤“Multiple identity columns specified for table 'TEST'. Only one identity column per table is allowed.“

 

CREATE TABLE dbo.TEST
(
    ID        INT IDENTITY(1,1) ,
    NAME        VARCHAR(32)
);
 
ALTER TABLE dbo.TEST ADD  ID1 INT IDENTITY(10,1)

 

 

2:標識列不能被更新。

 

 

   如果你更新標識列,就會遇到類似下面這樣的錯誤。

 

   Cannot update identity column 'xxx'.

 

 

3:SQL Server不能通過ALTER語句修改標識列的increment值大小。

 

如果非要調整標識列的increment值大小,只能通過重建表來實現。如果想通過增加列或刪除列的方法,非常麻煩。很多情況下也是不行的。例如,有些情況下需要你對新增的自增標識列更新資料才能保證資料一致性。還有一種非常規方法就是修改系統基表sys.syscolpars。這個後續整理一篇。

 

 

4:SQL Server不能通過ALTER語句修改表標識列的SEED的大小但是可以DBCC CHECKIDENT命令調整。SEED可以調大也可以調小,但是有一些限制!

 

#檢視某個表中的自增列當前的值:

DBCC CHECKIDENT (TableName,NORESEED)

 

#調整標識列的當前值(SEED)為50

DBCC CHECKIDENT('dbo.TEST', RESEED, 50);

 

通過DBCC CHECKIDENT命令調整SEED值大小,也是有限制的,如下實驗所示:

 

USE AdventureWorks2014;
GO
IF EXISTS (SELECT 1 FROM sys.objects WHERE type='U' AND name='TEST')
BEGIN
    DROP TABLE test;
END
GO
CREATE TABLE dbo.TEST
(
    ID        INT IDENTITY(1,1) ,
    NAME    VARCHAR(32)
);
 
INSERT INTO dbo.TEST
        (  NAME )
SELECT  'K1' UNION ALL
SELECT  'K2' UNION ALL
SELECT  'K3' UNION ALL
SELECT  'K4' UNION ALL
SELECT  'K5' UNION ALL
SELECT  'K6';
 
SET IDENTITY_INSERT dbo.TEST ON;
GO
INSERT INTO dbo.TEST
        ( ID, NAME )
SELECT 13, 'k13';
GO
SET IDENTITY_INSERT dbo.TEST OFF;
GO
 
DBCC CHECKIDENT(test)
 
DBCC CHECKIDENT('test', RESEED ,9);
 
 
 
INSERT INTO dbo.TEST
        (  NAME )
SELECT  'K9'  UNION ALL
SELECT  'K10' UNION ALL
SELECT  'K11' UNION ALL
SELECT  'K12' UNION ALL
SELECT  'K13' ;
SELECT * FROM dbo.TEST;

 

如果你修改一下表結構,標識列為主鍵或有唯一約束的話,

 

CREATE TABLE dbo.TEST
(
    ID        INT IDENTITY(1,1) PRIMARY KEY,
    NAME      VARCHAR(32)
);

 

那麼上面指令碼執行到插入資料時就會報主鍵衝突。錯誤如下所示:

 

 

Msg 2627, Level 14, State 1, Line 38

Violation of PRIMARY KEY constraint 'PK__TEST__3214EC2731C41DF1'. Cannot insert duplicate key in object 'dbo.TEST'. The duplicate key value is (13).

 

 

那麼接下來,我們將上面的指令碼稍微調整一下,你會看到完全不同的結果。如下所示:

 

USE AdventureWorks2014;
GO
IF EXISTS (SELECT 1 FROM sys.objects WHERE type='U' AND name='TEST')
BEGIN
    DROP TABLE test;
END
GO
CREATE TABLE dbo.TEST
(
    ID        INT IDENTITY(1,1) ,
    NAME      VARCHAR(32)
);
 
INSERT INTO dbo.TEST
        (  NAME )
SELECT  'K1' UNION ALL
SELECT  'K2' UNION ALL
SELECT  'K3' UNION ALL
SELECT  'K4' UNION ALL
SELECT  'K5' UNION ALL
SELECT  'K6';
 
SET IDENTITY_INSERT dbo.TEST ON;
GO
INSERT INTO dbo.TEST
        ( ID, NAME )
SELECT 13, 'k13';
GO
SET IDENTITY_INSERT dbo.TEST OFF;
GO
 
 
 
DBCC CHECKIDENT('test', RESEED ,9);
GO
DBCC CHECKIDENT(test);
GO
 
INSERT INTO dbo.TEST
        (  NAME )
SELECT  'K9'  UNION ALL
SELECT  'K10' UNION ALL
SELECT  'K11' UNION ALL
SELECT  'K12' UNION ALL
SELECT  'K13' ;
SELECT * FROM dbo.TEST;

 

這個是實驗測試時意外發現的一個問題,當時,它導致我得出不同的實驗結果,結論也搞錯了,問題出在DBCC CHECKIDENT (table_name),如果表的當前標識值小於標識列中儲存的最大標識值,則使用標識列中的最大值對其進行重置。我使用DBCC CHECKIDENT(test)本意是來檢視標識列的當前值,所以正確的做法應該用DBCC CHECKIDENT(test, NORESEED)這條命令。其實這裡也衍生了一個問題,由於可以人為調整SEED的值,所以標識列的值的唯一性,必須通過“PRIMARY KEY”或“UNIQUE”約束或者通過“UNIQUE”索引來實現。將欄位設定為標識列並不能保證值的唯一值。

 

 

5: 不能通過ALTER語句將已經存在的一個欄位改為標識列

 

CREATE TABLE dbo.TEST
(
    ID        INT ,
    NAME      VARCHAR(32)
);
 
--這種語法是不允許的
ALTER TABLE dbo.TEST  ALTER COLUMN ID IDENTITY(10,1) 

 

6:在記憶體優化表中,種子和增量必須分別設定為 1、1。 將種子或增量設定為 1 以外的值會導致以下錯誤:記憶體優化表不支援使用 1 以外的種子和增量值。另外,必須同時指定種子和增量,或者二者都不指定。 如果二者都未指定,則取預設值 (1,1)

 

 

7:如果事務回滾會導致標識列跳號。如下實驗所示,這種現象和Oracle、MySQL資料庫的行為一致。

 

            
           

相關推薦

SQL Server解惑——標識限制現象

  1:每個表只能建立一個標識列。   如下測試所示,如果表中有一個標識列,新增一個標識列就會遇到錯誤“Multiple identity columns specified for table 'TEST'. Only one identity column per table is a

SQL Server 2012-2016-2017 簡體中文版下載序列

ed2k://|file|cn_sql_server_2012_developer_edition_x86_x64_dvd_813281.iso|5054384128|AD91243654BB2FB7F74F26654134B91B|/ ed2k://|file|cn_sql_server_2012_st

SQL Server解惑——為什麼ORDER BY改變了變數的字串拼接結果

    在SQL Server中可能有這樣的拼接字串需求,需要將查詢出來的一列拼接成字串,如下案例所示,我們需要將AddressID <=10的AddressLine1拼接起來,分隔符為|。如下截圖所示。這種方式看起來似乎沒有什麼問題,而且簡單測試也是OK:   USE

SQL Server解惑&mdash;&mdash;查詢條件IN中能否使用變數

在SQL Server的查詢條件中,能否在IN裡面使用變數呢? 如果可以的話,有沒有需要注意的地方或一些限制呢?在回答這個問題前,我們先來看看這個例子:   IF EXISTS (SELECT 1 FROM sys.objects WHERE name='TEST' AND t

[翻譯]SQL Server等待事件&mdash;THREADPOOL

完全 ava 吃飯 onf 嘗試 mapping pan 因此 ble 原文:[翻譯]SQL Server等待事件—THREADPOOL 前言: 本文是對SQLSkills上一篇關於SQL Server中THREADPOOL等待的博客的翻譯,本文也不是

SQL SERVER重置自動編號(標識)

兩種方法: 一種是用Truncate TRUNCATE   TABLE  name 可以刪除表內所有值並重置標識值   二是用DBCC CHECKIDENT DBCC

Sql Server中判斷表、不存在則創建的方法[轉]

where art number primary net index mman www tro 一、Sql Server中如何判斷表中某列是否存在 首先跟大家分享Sql Server中判斷表中某列是否存在的兩個方法,方法示例如下: 比如說要判斷表A中的字段C是否存在兩個

BCP工具的使用以及C++,SQL server資料庫中呼叫命令的方法

BCP工具使用: BCP是由SYBASE公司提供的,專門用於資料庫表一級資料備份的工具。 主要引數如下: 基本用法: 遠端地址1的資料庫表student 匯出到本地(遠端ip1(10.189.1.1) ): bcp run.dbo.student out "c:\student

Coalesce (MS SQL Server)——取指定內容()中第一個不為空的值

oalesce 獲得引數中第一個不為空的表示式。 語法:        COALESCE ( expression [ ,...n ] )  例子:CREATE TABLE wages  &nbs

Sql Server 寫入指定自增的值 IDENTITY_INSERT

1.當資料庫表字段的列設定為自增列後,不能人為改變自增列的值 2.但有時候在導資料或公用配置過程中,有些基礎設定的值是不變的或者是固定,這樣在新起專案或導資料時會出現問題。 怎麼才能修改自增列的值,讓匯入的資料按我們指定的值存放呢, 網上各種方法均比較複雜,且操作不便利,

用VB程式碼在SQL SERVER 中建立資料庫,表,.以及對資料庫的操作

前面看了一編用VB程式碼建立ACCESS資料庫的文章,寫的很好.根據思路,寫下建立SQL 資料庫的方法,供大家參考.1:引用ADO2.5lib2:在窗體上新增一個按鈕COMMAND13:按鈕程式碼如下:Private Sub Command1_Click()Dim cnn A

SQL server重啟管理命令以及SQL Server啟動的幾種方法

通過SQL Server命令列啟動及停止SQL服務的方法 在SQL Server中,想要啟動或停止SQL Server服務,通過SQL Server命令列操作就可以實現了。下面為您介紹詳細的實現步驟,希望對您能有所幫助。 操作步驟如下: (1)在作業系統的工作列中單擊“開

SQL Server 如何查詢表定義的索引信息

信息 eat str exe 多個 中文 時間 column 顯示 如何用一種很直觀的方式查詢出數據庫中所有表的定義信息以及相關索引信息,針對喜歡中文顯示的童鞋: SELECT 表名=CASE WHEN C.column_id=1 THEN O.name ELSE

SQL SERVER中強制類型轉換castconvert的區別

varchar 時間 bold 功能 one 轉換 輸出 class 和數 在SQL SERVER中,cast和convert函數都可用於類型轉換,其功能是相同的, 只是語法不同. cast一般更容易使用,convert的優點是可以格式化日期和數值. 1 select

SQL Server 2014存儲過程的備份還原

語句 誤刪除 記事本 nbsp 位置 管理軟件 使用 恢復 ima Sql Server 2014存儲過程備份和恢復... 1 1、 備份存儲過程:... 1 2、 還原... 8 Sql Server 2014存儲過程備份和恢復 1、 備份存儲過程

翻譯— 通往SQL Server代理的階梯-二級:作業步驟子系統

核心 success 文件 server 下一個 技術分享 logs 2.0 觀察 通往SQL Server代理的階梯-二級:作業步驟和子系統 Richard Waymire,2017/10/11(首次出版:2011/02/17) 該系列 本

翻譯(十四)——通往SQL Server代理的階梯-二級:作業步驟子系統

完成後 進入 多個 語言 實例 是我 屏幕 回顧 b+ 翻譯(十四)——通往SQL Server代理的階梯-二級:作業步驟和子系統 Richard Waymire,2017/10/11(首次出版:2011/02/17)

通往SQL Server代理的階梯-二級:作業步驟子系統

通過 想要 工作 文件 bubuko checkdb 實時數據 操作類 tegra 轉載自:http://www.sqlservercentral.com/articles/SQL+Agent/Job+Steps+and+Subsystems/72268/ 通往SQL Se

Sql Server中的數據類型Mysql中的數據類型的對應關系(轉)

bool script 根據 文本 article 自己 bigint 表格 eight Sql Server中的數據類型和Mysql中的數據類型的對應關系(轉):https://blog.csdn.net/lilong329329/article/details/7889

SQL Server語句創建數據庫表——並設置主外鍵關系

_id stun .cn rim 執行 sco 技術 core 變量 簡單的創建數據庫的 SQL 語句: 1 use master 2 go 3 4 if exists(select * from sysdatabases where name=‘Test‘)