Groups | Blog | Home
all groups > sql server new users > may 2005 >

sql server new users : IDENTITY column


Lisa Pearlson
5/24/2005 12:00:00 AM
I posted this on .programming, but got no response.. maybe because it's a
newbie question:

Hi,

Do many people use the IDENTITY type for a column?
The advantage is that every time you add a row, that identity column is
automatically incremented, however, I have always wondered about the
following issues that I could try to test and find out, but my testing will
not necessarily reveil all there is to know that you might know off the top
of your heads.

1) can you manually insert an identity? for example, row 1, 2 and 3 already
exist and I manually INSERT a row with id 5, what will happen when identity
reaches 4 and wish to move to 5? will it skip 5 because it already exists,
overwrite it, or what?

2) What happens if identity reaches maximum? If INDENTITY is reset, while
rows already exist, what will happen to existing rows? See question 1.

3) identity keeps moving up.. if later rows are deleted, gaps are formed.
How can this be prevented? Is there a way to find most efficiently which
ID's are available?

So basically, imagine I have a table like this:

CREATE TABLE MyTable (
Id IDENTITY(1,1) PRIMARY KEY,
OtherData TEXT
)
GO

INSERT INTO MyTable(OtherData) VALUES ("test1")
INSERT INTO MyTable(OtherData) VALUES ("test2")
INSERT INTO MyTable(OtherData) VALUES ("test3")
INSERT INTO MyTable(OtherData) VALUES ("test4")
INSERT INTO MyTable(OtherData) VALUES ("test5")

DELETE FROM MyTable WHERE Id=2 OR Id=4

Now I wish to have a query that gives the available id's back (2 and 4 in
this case).
The problem is, how do you info about rows that do not exist?
Only way I can think of is get MAX(Id) and then loop through all values in
descending order until you find one that doesn't exist, testing each one.
And this can become very slow in case of many records, and can't be the way.

Any suggestions? How are IDENTITY columns used? Just keep letting it go up
until it runs out? I know this would take millions of records maybe and in
real life situations may never happen, but theoretically, it just doesn't
sound right.
rows will get deleted and added and at some point in the future, I will have
reached the ceiling because deleted id's are never reused.

Or is it much better to use a "FindFreeId" type of stored procedure or
whatever, wit or without an IDENTITY column?

Lisa


Chandra
5/24/2005 8:51:02 PM
Hi

Check for:
DBCC CHECKIDENT and
SET IDENTITY_INSERT
in books online. This will answer your questions

--
best Regards,
Chandra
http://chanduas.blogspot.com/
http://groups.msn.com/SQLResource/
---------------------------------------



[quoted text, click to view]
Hugo Kornelis
5/25/2005 12:00:00 AM
[quoted text, click to view]

Hi Lisa,

On the contrary - you got lots of responses. Here's a link to your
message plus all replies in Google's archives:

http://groups-beta.google.com/group/microsoft.public.sqlserver.programming/browse_frm/thread/43fa7dd621aacbd0/7f9fe8223d4237a7?hl=en#7f9fe8223d4237a7


Best, Hugo
--

Lisa Pearlson
5/25/2005 12:00:00 AM
Hey, how is that possible? Why do I find those responses via google, but
don't find them using outlook express?
I mean, I can read your response right here, but I can't find those
responses from the other people, while they did come up via google as you
suggested.. how is this possible?

Lisa


[quoted text, click to view]

Hugo Kornelis
5/25/2005 12:00:00 AM
[quoted text, click to view]

Hi Lisa,

No idea. I use agent (a dedicated newsreader from Forte inc., can be
downloaded from www.forteinc.com). The only times I miss a post is when
it falls foul of my news provider's filters (usually spam, excessive
crossposts, or posts from the future or from the deep past).

Maybe you should ask in a Outlook- or Office group?

Best, Hugo
--

Lisa Pearlson
5/25/2005 12:00:00 AM
None of the replies answered the second half of my question though...
I asked if IDENTITY column was used often.. learned that puritans think it
sux (and that it should be spelled sucks) while others think it's
convenient. I'm not a guru, but I don't like it either for serious
applications.

So my second part of the question was, which query would find an "available
index slot" most efficiently?

Imagine I have the indexes 1, 2, 3, 5, 6, 9

I want a query that finds a 'freeId', in the above cases it would return 4
if 4, 7 and 8 are found and used, it would find 10, 11, etc.

The generic problem I face is, how do I find values that do NOT exist
efficiently?
You first get MAX(Id) and then can do a for/next loop kinda thing to find an
id, but that's very slow in case of large number of records. I wonder if
there's even a set based query possible.. though using a stored procedure is
no problem and even preferred. Just wondering.

Lisa

[quoted text, click to view]

Hugo Kornelis
5/25/2005 12:00:00 AM
[quoted text, click to view]

(snip)
[quoted text, click to view]

Hi Lisa,

To return the lowest unused value:

SELECT MIN(a.id) + 1 AS "first avaialable"
FROM MyTable AS a
LEFT JOIN MyTable AS b
ON b.id = a.id + 1
WHERE b.id IS NULL


To return the start and end of each range of available values:

SELECT a.id + 1 AS "start of range",
(SELECT MIN(c.id)
FROM MyTable AS c
WHERE c.id > a.id) - 1 AS "end of range"
FROM MyTable AS a
LEFT JOIN MyTable AS b
ON b.id = a.id + 1
WHERE b.id IS NULL


To return all available values individually, the best way is to create
and populate a numbers table (once!), then use an outer join strategy:

SELECT n.Number AS "available"
FROM Numbers AS n
LEFT JOIN MyTable AS b
ON b.id = n.Number
WHERE b.id IS NULL
AND n.Number <= (SELECT MAX(id) + 5
FROM MyTable)

Best, Hugo
--

Hugo Kornelis
5/25/2005 12:00:00 AM
[quoted text, click to view]

(snip)

Oops - forgot to add this to my reply:

If you choose to use the approach with the numbers table, here's a link
to an article that describes how to make one and various ways to use
one: http://www.aspfaq.com/show.asp?id=2516.

Best, Hugo
--

AddThis Social Bookmark Button