Handling identity columns in an "Insert Into TABLE Values()" statement?

150,003

Solution 1

By default, if you have an identity column, you do not need to specify it in the VALUES section. If your table is:

ID    NAME    ADDRESS

Then you can do:

INSERT INTO MyTbl VALUES ('Joe', '123 State Street, Boston, MA')

This will auto-generate the ID for you, and you don't have to think about it at all. If you SET IDENTITY_INSERT MyTbl ON, you can assign a value to the ID column.

Solution 2

Another "trick" for generating the column list is simply to drag the "Columns" node from Object Explorer onto a query window.

Solution 3

The best practice is to explicitly list the columns:

Insert Into TableName(col1, col2,col2) Values(?, ?, ?)

Otherwise, your original insert will break if you add another column to your table.

Solution 4

You have 2 choices:

1) Either specify the column name list (without the identity column).

2) SET IDENTITY_INSERT tablename ON, followed by insert statements that provide explicit values for the identity column, followed by SET IDENTITY_INSERT tablename OFF.

If you are avoiding a column name list, perhaps this 'trick' might help?:

-- Get a comma separated list of a table's column names
SELECT STUFF(
(SELECT 
',' + COLUMN_NAME AS [text()]
FROM 
INFORMATION_SCHEMA.COLUMNS
WHERE 
TABLE_NAME = 'TableName'
Order By Ordinal_position
FOR XML PATH('')
), 1,1, '')

Solution 5

Since it isn't practical to put code in a comment, in response to your comment in Eric's answer that it's not working for you...

I just ran the following on a SQL 2005 box (sorry, no 2000 handy) with default settings and it worked without error:

CREATE TABLE dbo.Test_Identity_Insert
(
    id  INT IDENTITY NOT NULL,
    my_string   VARCHAR(20) NOT NULL,
    CONSTRAINT PK_Test_Identity_Insert PRIMARY KEY CLUSTERED (id)
)
GO

INSERT INTO dbo.Test_Identity_Insert VALUES ('test')
GO

SELECT * FROM dbo.Test_Identity_Insert
GO

Are you perhaps sending the ID value over in your values list? I don't think that you can make it ignore the column if you actually pass a value for it. For example, if your table has 6 columns and you want to ignore the IDENTITY column you can only pass 5 values.

Share:
150,003
James McMahon
Author by

James McMahon

Blogging at https://dev.to/jamesmcmahon.

Updated on September 13, 2020

Comments

  • James McMahon
    James McMahon over 3 years

    In SQL Server 2000 or above is there anyway to handle an auto generated primary key (identity) column when using a statement like the following?

    Insert Into TableName Values(?, ?, ?)
    

    My goal is to NOT use the column names at all.

  • James McMahon
    James McMahon almost 15 years
    Just to clarify, by explicit values you mean you have to query the database to see what the next identity in the sequence would be and insert it manually?
  • Mitch Wheat
    Mitch Wheat almost 15 years
    No, you can use any value that is not already there, but the next in sequence will start from the greatest plus one....
  • Mitch Wheat
    Mitch Wheat almost 15 years
    It tends only to be used when you have something like reference data that is required to have the exact same ID values across different application installations
  • James McMahon
    James McMahon almost 15 years
    Oh really? That is fantastic. I had just assumed that wouldn't work. Let me give that try.
  • Mitch Wheat
    Mitch Wheat almost 15 years
    @Eric is correct that what's I meant in point 1 above (have edited to show my intent), +1
  • James McMahon
    James McMahon almost 15 years
    Eric this isn't working for me at all. It is complaining that I have, identity insert off, I assume because it is trying to insert the first item in values into ID. Anything specific you have to set to get it to ignore the first column?
  • Eric
    Eric almost 15 years
    Don't put the ID column in the insert statement if you want SQL Server to autogenerate the ID for you.
  • Mitch Wheat
    Mitch Wheat almost 15 years
    don't set identity insert off when leaving identity column out of the coolumn list, otherwise a value will not be generated for it
  • James McMahon
    James McMahon almost 15 years
    @Eric, I didn't specify any columns. I ran INSERT INTO MyTbl VALUES ('TEST1', 'TEST2', 'TEST3', 'TEST4') on a table with 5 columns, the first being an autogenerated ID column. The database is trying to put 'TEST1' into the ID column.
  • James McMahon
    James McMahon almost 15 years
    I am testing this out on SQL Server 2005 express, just FYI.
  • James McMahon
    James McMahon almost 15 years
    I think my issue is that when I run the query in the SQL server query window it translates it into INSERT INTO (ColumnName, ColumnName ... etc), anyway to avoid this?
  • James McMahon
    James McMahon almost 15 years
    Yeah my boss actually said the same thing. Both of you are completely right, but the data in this database is in-permit (i.e. wiped out and regenerated daily) so if something like this happened it wouldn't be the end of the world.
  • dburges
    dburges almost 15 years
    Do NOT ever use Set identity_insert on in a production environment! Not unless you want other users inserting to the table to have issues. This is only to be used when transferring large amounts of data from one system to another and should only be done in single-user mode.
  • Mitch Wheat
    Mitch Wheat almost 15 years
    @HLGEM: I'm not suggesting you leave it turned on! But you are correct that it should ideally be done when there is no activity on that table. We use it mainly on reference data tables, when there is never any insert activity during normal use.
  • Shiraz
    Shiraz over 4 years
    I think it would be better if the original insert breaks if another column is added - it makes sure the insert caters for all fields (although NOT NULL settings on fields could also be used to enforce entry)