views:

68

answers:

1

Hi Guys,

Could you please help me with this one:

In one of my scripts I am inserting some data in to some table "Item". One of the columns in the "Item" table is "ItemNumber".

I want to be able to call some function (most probably a Stored proc) where it would return me a numeric number which I can use for the ItemNumber.

I CAN NOT use AutoIncrement because ItemNumber is unique and there might be a collision when in a differnt script I am inserting data in "Item", which already has "ItemNumber"

I only know the Max number for the "ItemNumber" and I am free to use anything after that.

I need a table for this storedProc to store the next number to be used, right?

I was thinking of creating a one column table with the MaxNumber in it and a storedproc where it would return me the MaxNumber and also increment the MaxNumber by 1 for the next use

I need help writing the stored proc and it usage with in the INSERT INTO Item call.

EDIT:

Basically I am grabbing data from 5 old tables where ItemNumber is either NULL or set. For the ones which are set they are all unique numbers. For the data where the ItemNumber is NULL I want to assign it, what the best approach?

Help please!

Thanks,

Voodoo

+2  A: 

(Assuming SQL Server - probably applies to most SQL implementations)

If you use IDENTITY constraint on your field, the server will not allow there to be duplicate instances. As one of the comments notes, the value is calculated on the server in this case, and your application does not (and under normal circumstances cannot) provide it.

Note that the server does not guarantee that the numbers will be contiguous - should you do an insert, and abort the transaction, the value that would have been used would be 'lost' - the server will not offer it again.

If you need to have contiguous ID numbers, you will need to have serlialised access to update the table, which you would need to manage and which would not be efficient. (You can still declare it to be an IDENTITY column, but would need to set IDENTITY_INSERT On for the table for each update.)

Additional:

Possibly a bit of a kludge, but might work for a one-off scenario. Have you considered copying the data into a new table, where the ID is set, then applying the IDENTITY constraint, and inserting the ones with NULL IDs (allowing the server to allocate them for you?) That might fix your specific issue here.

Ragster
Thanks, one more question: let's say using IDENTITY the server gives me 33 to be used for the ItemNumber, what happens when I try to insert (using Identity_Insert like you suggested) which has 33 as the ItemNumber? That would cause a collision and would not work. I need to keep the ItemNumbers same as before and only assign the ones which are null.
VoodooChild
If you are using Identity fields, you wouldn't normally want to specify the value yourself - the point is that you let the server do it (in a consistent thread-safe manner.)IDENTITY_INSERT is for when you wish to overrule the server for some very good reason, and shouldn't be a normal operation. (We use it for a specific table, where the values have to match another identy field for technical reasons, and the very occasional manual data repair - very much the exceptional cases.)
Ragster
(cont.) However - if you have existing data in the table, you can apply the constraint with NOCHECK, and it will only apply the rule to new inserts. You can manually change existing ones (within the rules for the field.) The server will never insert a number that already exists for an identity field. It doesn't 'give' you the number for you to insert - you ask for record insert and it does it, generating the number for you. You can then ask it what the last inserted identity was.
Ragster
I added a brief kludge suggestion that might fix your specific issue. I wouldn;t recommend it for general use!
Ragster
Thanks, I will try to see if this works!
VoodooChild