What the missing numbers in an identity column with MSSQL

Identity columns provide automatic, almost incremental, numbering. You can only have 1 identity column per table.

  • Should be an int, smallint, tinyint, decimal or numeric with scale 0.
  • Can't contain nulls.
  • Can't have any default.
  • The increment is an integer value (1, 10,...) and can not contain decimals. Also, it can't be a 0 increment.
  • Each value is unique.
  • There is no guarantee that it's a consecutive increment, even if the increment is 1.
  • Identity number are NEVER reused, even if somebody delete rows or even the last row.
  • NEVER use identity for invoice numbers, cheque numbers.

Data used

  1. USE sql911;
  2. go
  3.  
  4. SELECT sales_id, sales_date, sales_qty, emp_short
  5. FROM sales02;
  6. go
sales_id    sales_date              sales_qty                               emp_short
----------- ----------------------- --------------------------------------- --------------------------------------------------
1           2005-10-06 10:01:01.000 10.00                                   000310
2           2006-10-06 10:01:01.000 10.00                                   000310
3           2005-11-06 10:01:01.000 9.00                                    000110
4           2006-10-06 10:01:01.000 10.00                                   000310
5           2005-12-06 11:01:01.000 8.00                                    000010
6           2006-02-06 13:01:01.000 6.00                                    000190
11          2006-05-06 16:01:01.000 3.00                                    000010
12          2004-10-06 10:01:01.000 10.00                                   000310
13          2005-11-06 10:01:01.000 9.00                                    000010
14          2006-06-06 17:01:01.000 2.00                                    000190
15          2006-01-06 12:01:01.000 7.00                                    000310
16          2006-02-06 13:01:01.000 6.00                                    000110
17          2005-03-06 14:01:01.000 5.00                                    000190
18          2006-10-06 10:01:01.000 10.00                                   000110
19          2006-10-06 10:01:01.000 3.00                                    000110
26          2006-10-06 10:01:01.000 10.00                                   000030
27          2004-03-06 14:01:01.000 5.00                                    000110
28          2005-04-06 15:01:01.000 4.00                                    000010
29          2005-05-06 16:01:01.000 3.00                                    000190
31          2006-07-06 19:01:01.000 1.00                                    000310
32          2006-03-06 14:01:01.000 5.00                                    000310
33          2006-04-06 15:01:01.000 4.00                                    000010
35          2006-06-06 17:01:01.000 2.00                                    000110
41          2007-05-07 11:30:00.000 2.00                                    000030
42          2007-05-08 13:30:00.000 1.00                                    000030
43          2006-07-06 19:01:01.000 1.00                                    000010
44          2007-05-09 14:00:00.000 1.25                                    000110
45          2007-11-06 10:01:01.000 9.00                                    000030
46          2007-05-10 14:00:00.000 5.00                                    000190
47          2007-05-11 14:15:00.000 4.00                                    000190
48          2007-05-12 15:00:00.000 2.00                                    000190
49          2007-05-13 16:00:00.000 1.00                                    000190

(32 row(s) affected)

Missing identity numbers in MSSQL

There are many ways of getting a list of the missing numbers in MSSQL.

  • My favorite is a number table. I personally use the number table for numbers but also for wording the cheque amounts.
  • A simple self link will only give the first number that is missing, even if the gap is more than 2 numbers.
  1. SELECT nums
  2. FROM num
  3. WHERE num < 10;
  4. go
num
-----------
1
2
3
4
5
6
7
8
9

(9 row(s) affected)
  1. SELECT num AS 'Missing sales_id'
  2. FROM nums
  3. WHERE num not in (
  4.   SELECT sales_id  FROM sales02)
  5.   and num <= (SELECT MAX(sales_id) FROM sales02);
  6. go
Missing sales_id
----------------
7
8
9
10
20
21
22
23
24
25
30
34
36
37
38
39
40

(17 row(s) affected)

@@identity

To find out what is the current identity value for a table:

  1. DBCC CHECKIDENT ('sales02', NORESEED);
  2. go
Checking identity information: current identity value '57', current column value '57'.
DBCC execution completed. If DBCC printed error messages, contact your system administrator.

Note that is is the current number, not the next value that will be used.

By the way:

  1. SELECT SCOPE_IDENTITY() AS 'Last identity used';
  2. go
  3.  
  4. LAST IDENTITY used
  5. ---------------------------------------
  6. NULL
  7.  
  8. (1 ROW(s) affected)
  9.  
  10. SELECT @@IDENTITY  AS 'Last identity used';
  11. go
  12.  
  13. LAST IDENTITY used
  14. ---------------------------------------
  15. NULL
  16.  
  17. (1 ROW(s) affected)

We get a null value, because, there was no INSERT. The new identity only happens on INSERTs.