Q 1:
I have a empty table to insert records. Having one column of IDENTITY type, for which I want to insert values manually.
Example:
Table: Employee
create table Employee
(
ID int IDENTITY(1,1) PRIMARY KEY,
LastName varchar(255) NOT NULL,
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
Inserting records:
SET IDENTITY_INSERT Employee ON;
insert into Employee values(101,'ABC','XYZ','HighStreet','Moscow')
Error:
Msg 8101, Level 16, State 1, Line 1
An explicit value for the identity column in table 'Employee' can only be specified when a column list is used and IDENTITY_INSERT is ON.
Q 2:
How to get latest inserted ID of an Employee without using MAX and Top?
Answer 1
If you will try to insert the value into Identity column you will get the error
Cannot insert explicit value for identity column in table ‘Employee’
when IDENTITY_INSERT is set to OFF.
Write SET IDENTITY_INSERT table name ON before the insert script and
SET IDENTITY_INSERT table name Off after insert script
SET IDENTITY_INSERT Employee ON
insert into Employee(ID,LastName,FirstName,Address,City) values
(101,'ABC','XYZ','HighStreet','Moscow')
SET IDENTITY_INSERT Employee OFF
Answer 2
There are several ways using like this after insert statement
After an INSERT, SELECT INTO, or bulk copy statement is completed,
##IDENTITY contains the last identity value that is generated by the
statement
SELECT ##IDENTITY
It returns the last IDENTITY value produced on a connection,
regardless of the table that produced the value, and regardless of the
scope of the statement that produced the value.
SELECT SCOPE_IDENTITY()
It returns the last IDENTITY value produced on a connection and by a
statement in the same scope, regardless of the table that produced the
value.
SELECT IDENT_CURRENT(‘Employee’)
It returns the last IDENTITY value produced in a table, regardless of
the connection that created the value, and regardless of the scope of
the statement that produced the value. IDENT_CURRENT is not limited by
scope and session; it is limited to a specified table. IDENT_CURRENT
returns the identity value generated for a specific table in any
session and any scope.
MSDN SOURCE
You can use IDENT_CURRENT( 'table_name' ) to get the current value.
For external value of Identity column Column Name given explicitly is Must as below
SET IDENTITY_INSERT Employee ON;
insert into Employee(ID ,LastName,FirstName,Address,City)
values(101,'ABC','XYZ','HighStreet','Moscow')
Related
Im trying to update a table I have the same Data but with different ID's so i would like to set the ID of both communs to the lowest ID register for the results.
UPDATE TABLENAME
SET EXAMPLEID = LOWER(EXAMPLEID)
WHERE
TID = TID
AND
KID = KID
AND
STREET = STREET
I'm getting the following error:
Msg 8102, Level 16, State 1, Line 1 Cannot update identity column
'EXAMPLEID'
Identity Column is generally used with Primary Key column. In your case if ExampleID is your primary key and also identity Column, You cannot have same ExampleID on two different rows.
Primary Key Column is unique for every row
On the other hand If your column is not PK but Identity Column, then SQL Server does not allow you to update Identity Key Column Value.
But there is a dirty workaround alternative for this (Not Recommended)
You can't update an identity column. You may insert new records with an explicit value using IDENTITY_INSERT, but SQL Server won't let you do an update.
If you really need to do this, the only option you have is to copy the full table temporarily and recreate your final table again with the updated values. This is strongly NOT recommended:
Create a copy of your table, with all related objects (indexes, constraints, etc.), but with no rows (only schema objects).
CREATE TABLE TABLENAME_Mirror (
ExampleID INT IDENTITY,
TID VARCHAR(100),
KID VARCHAR(100),
STREET VARCHAR(100))
Set IDENTITY_INSERT ON on this new table and insert the records with the updated values.
SET IDENTITY_INSERT TABLENAME_Mirror ON
INSERT INTO TABLENAME_Mirror (
ExampleID,
TID,
KID,
STREET)
SELECT
/*Updated values*/
FROM
--....
SET IDENTITY_INSERT TABLENAME_Mirror OFF
Drop the original table and rename the copied one to the original name:
BEGIN TRANSACTION
IF OBJECT_ID('dbo.TABLENAME') is not null
DROP TABLE dbo.TABLENAME
EXEC sys.sp_rename
'dbo.TABLENAME_Mirror',
'TABLENAME'
COMMIT
You might need to reseed the identity with a proper value once the rows are inserted, if you want to keep the same seed as before.
insert into Student
values('1', 'joedio', 'newyark', GETDATE())
I get this error message when trying to run this SQL:
An explicit value for the identity column in table 'Student' can only be specified when a column list is used and IDENTITY_INSERT is ON.
If you wants to insert primary key by query even it is auto increment then you have to set IDENTITY_INSERT ON as below, it will allow you to insert unique value by query:
SET IDENTITY_INSERT [Tablename] ON;
Your query will be now:
SET IDENTITY_INSERT Student ON;
INSERT INTO Student VALUES('1','joedio','newyark',GETDATE());
SET IDENTITY_INSERT Student OFF;
If you wants that SQL manage it self then default it set to IDENTITY_INSERT OFF and Auto increment is set, means on every insert the new value is assigned to that PK column.
Better to execute with default setting SET IDENTITY_INSERT Student OFF because by manual inset possibility to insert duplicate value and it will throw an error.
If your table has Identity Column, then you have to mention all the other columns while inserting.
Just it is for sample:
INSERT INTO Student (ID, Name, State, Date) VALUES('1','joedio','newyark',GETDATE())
If the First column is Identity, then skip the value while inserting:
INSERT INTO Student (Name, State, Date) VALUES('joedio','newyark',GETDATE())
And If you want to Insert Values into an Identity Column in SQL Server
SET IDENTITY_INSERT IdentityTable ON
INSERT INTO Student (ID, Name, State, Date) VALUES('1','joedio','newyark',GETDATE())
SET IDENTITY_INSERT IdentityTable OFF
And also refer the link How to Insert Values into an Identity Column in SQL Server for More information.
Try to clear out this concept by taking a look at it.
IDENTITY (Property)
And after mentioning the primary key as identity, you need not to pass an argument for its value. Its value will be auto incremented.
TRY THIS: If you really want to insert value in the IDENTITY column then use one of the given answers as
SET IDENTITY_INSERT [Tablename] ON;
INSERT INTO [Tablename]..........
SET IDENTITY_INSERT [Tablename] OFF;
Otherwise, just get rid off the error exclude the first value from the values
INSERT INTO Student --No need to add column definition if you are inserting rest of all
VALUES('joedio', 'newyark', GETDATE()) --Error Free
In sql server when ID column is Auto Incremental and you are passing ID
IF NOT EXISTS (SELECT * FROM Student WHERE ID = 1)
THEN
SET IDENTITY_INSERT Student ON;
INSERT INTO Student (ID, Name, State, Date) VALUES('1','joedio','newyark',GETDATE())
SET IDENTITY_INSERT Student OFF;
END
2.In sql server when ID column is Auto Incremental and you are not passing ID
INSERT INTO Student (Name, State, Date) VALUES('joedio','newyark',GETDATE())
3.In My sql use can use
INSERT IGNORE INTO Student (ID, Name, State, Date) VALUES('1','joedio','newyark',GETDATE());
OR
INSERT IGNORE INTO Student (Name, State, Date) VALUES('joedio','newyark',GETDATE());
IDENTITY_INSERT allows explicit values to be inserted into the identity column of a table.
Use this query and set IDENTITY_INSERT on the table 'on'
SET IDENTITY_INSERT Student ON
Note: At any time, only one table in a session can have the IDENTITY_INSERT property set to ON.
SET IDENTITY_INSERT Student ON;
INSERT INTO Student (RegNo, Name, Address, CreatedTime) VALUES('2','calibio','newyark',GETDATE());
SET IDENTITY_INSERT Student OFF;
I can't figure out what I am doing wrong.
This is my code
SET IDENTITY_INSERT [Erea_Local].[Domain].[BlikAfmeting] ON
INSERT INTO [Erea_Local].[Domain].[BlikAfmeting]
SELECT *
FROM [dbo].[BlikAfmetings]
SET IDENTITY_INSERT [Erea_Local].[Domain].[BlikAfmeting] OFF
This is the error
An explicit value for the identity column in table 'Erea_Local.Domain.BlikAfmeting' can only be specified when a column list is used and IDENTITY_INSERT is ON.
If I only run the set IDENTITY INSERT .....
I get the message command completed
According the message:
An explicit value for the identity column in table
'Erea_Local.Domain.BlikAfmeting' can only be specified when a column
list is used and IDENTITY_INSERT is ON.
You should use a column list of values.
I've got a few tables linked together where data should be inserted to using a stored procedure. The tables are:
create table contactpersoon
(
contactpersoonnr integer identity(1,1),
klantnr integer,
naam varchar(50) not null,
telefoonnr varchar(10) not null,
emailadres varchar(50) not null,
constraint pk_contactpersoon
primary key(contactpersoonnr, klantnr),
constraint fk_contactpersoon_klantnr
foreign key(klantnr) references klant(klantnr)
)
create table klant
(
klantnr integer identity(1,1) primary key,
bedrijfsnaam varchar(50) not null
)
create table Logins
(
GebruikersNaam varchar(30),
Wachtwoord varchar(30),
Klantnr int,
MdwNr int,
constraint pk_logID primary key(GebruikersNaam),
constraint fk_klantnr foreign key(klantnr) references klant(klantnr),
constraint fk_mdwnr foreign key(mdwnr) references medewerker(mdwnr)
)
Stored procedure for adding data to these tables:
IF EXISTS (SELECT * FROM sys.objects WHERE type = 'P' AND name = 'spKlantAanmaken')
DROP PROCEDURE spKlantAanmaken
GO
Create Procedure spKlantAanmaken
(
#bedrijfsnaam as varchar(255),
#contactnaam as varchar(255),
#telnr as integer,
#email as varchar(255),
#gebruikersnaam as varchar(255),
#wachtwoord as varchar(255)
)
AS
Begin transaction
Declare #klantnr integer
Declare #contactpersoonnr integer
Insert into Klant Values (#klantnr, #bedrijfsnaam);
Insert into contactpersoon values(#contactpersoonnr, #klantnr, #contactnaam, #telnr, #email);
Insert into Logins values (#gebruikersnaam, #wachtwoord ,#klantnr, NULL);
Select * from contactpersoon
IF ##ERROR <> 0
BEGIN
ROLLBACK
RAISERROR ('Error tijdens uitvoeren van stap 2.', 16, 1)
RETURN
END
COMMIT
GO
I don't know if it is necessary to use these identity values in the inserts.
If I try this stored procedure I get the following error:
Msg 8101, Level 16, State 1, Procedure spKlantAanmaken, Line 923
An explicit value for the identity column in table 'Klant' can only be
specified when a column list is used and IDENTITY_INSERT is ON.
If I remove the identity values from the insert I get this error:
Msg 213, Level 16, State 1, Procedure spKlantAanmaken, Line 923
Column name or number of supplied values does not match table definition.
What am I doing wrong?
When you use Identity, the columns on which the identity is applied need not be in your INSERT statement VALUES. So edit your code like below
EDIT
It also seems you are missing out the columns you are trying to insert into
Insert into Klant (bedrijfsnaam) Values (#bedrijfsnaam)
Insert into contactpersoon (klantnr, contactnaam, telnr, email) Values (#klantnr, #contactnaam, #telnr, #email)
It seems all the answers saying the same thing so hope your issued is solved
Since you have identity columns, you must specify the list of columns to insert into, in your INSERT statement, and not supply a value for the identity column - like this:
Instead of
Insert into Klant Values (#klantnr, #bedrijfsnaam);
use
Insert into Klant(bedrijfsnaam) Values (#bedrijfsnaam);
and do this for all your INSERT operations.
This is a generally accepted "Best Practice" for any time you insert something into a table - it is recommend to always explicitly specify the list of columns in your table that you're inserting into (to avoid annoying errors and surprises).
Avoid the identity columns klantnr, contactpersoonnr in the INSERT query and explicitly define your column names:
So the below code will work in your case:
Insert into Klant(bedrijfsnaam) Values (#bedrijfsnaam);
Insert into contactpersoon(klantnr, naam, telefoonnr, emailadres) values(#klantnr, #contactnaam, #telnr, #email);
Just specify the column names AND the contents in the INSERT statement like:
INSERT INTO klant (bedrijfsnaam) VALUES ('XYZ');
If you don't specify the column name list, the SQL interpreter implies, you want the identity column, too. In this case you would want to set data for 2 columns, but only provide one content element, which explains the latter error message.
Edit these two lines in your SP
Insert into Klant (bedrijfsnaam)
Values (#bedrijfsnaam);
Insert into contactpersoon(klantnr,naam,telefoonnr,emailadres)
values(#klantnr, #contactnaam, #telnr, #email);
Provide a column list, excluding the identity columns in the insert statements
I have the following table:
CREATE TABLE [dbo].[Subject] (
[SubjectId] INT IDENTITY (1, 1) NOT NULL,
[Name] NVARCHAR (50) NOT NULL,
[Version] ROWVERSION NOT NULL,
[CreatedBy] NVARCHAR (128) NOT NULL,
[CreatedDate] DATETIME NOT NULL,
[ModifiedBy] NVARCHAR (128) NOT NULL,
[ModifiedDate] DATETIME NOT NULL,
CONSTRAINT [PK_Subject] PRIMARY KEY CLUSTERED ([SubjectId] ASC)
);
I would like to create a new row that is a copy of a row with SubjectId 2 but I want the new row to have a SubjectId of 0. Is there a way that I can turn the identity off and insert the new row as a copy of the row with SubjectId 2. Note that I don't want to turn identity on again.
Following Jen's answer now I have:
SET IDENTITY_INSERT Subject OFF
insert into Subject select 0,Name,version, createdby,createddate,modifiedby,modifiedDate from subject where subjectid=2
Which gives another error:
Msg 8101, Level 16, State 1, Line 4
An explicit value for the identity column in table 'Subject' can only be specified when a column list is used and IDENTITY_INSERT is ON.
SET IDENTITY_INSERT Subject ON means you can explicitly insert values into an identity column in Subject table.
Therefore if you want to insert values explicitly into an identity column you will TURN ON this feature and once you have added the value into identity column you will need to turn it OFF .
Note
Also when you have Identity_Insert on you have to mention the column names in your insert statement explicitly.
Something like this....
SET IDENTITY_INSERT Subject ON;
INSERT INTO Subject (subjectid,Name,version, createdby,createddate,modifiedby,modifiedDate)
SELECT 0,Name,version, createdby,createddate,modifiedby,modifiedDate
FROM subject
WERE subjectid = 2
SET IDENTITY_INSERT Subject OFF;
One more Important thing. Since you are inserting values explicitly into your identity column, not in this particular case but when you insert a value that has not been generated by the Identity column yet, later on when you have identity insert off and you expect identity column to generate values for you, and if you have a Unique Index or a Primary key constraint on that column, Identity column will generate values that you might have already inserted explicitly, which will result in duplicates in your primary key column(obviously sql server wont let this happen) and you will get an error something like... "Duplicate value in Primary key column".
To avoid this you can reseed you identity column to skip these values you have inserted explicitly by doing what is shown below after your explicit inserts in identity column.
DBCC CHECKIDENT(Table_Name, RESEED, 0) --<-- some smallest value
DBCC CHECKIDENT(Table_Name, RESEED) --<-- without any seed value
This will reset the identity column to next highest available identity value.
Most Important Note
If it is an Identity value, leave it alone, dont mess with it, let it generate values for you, If you do need to influence the values being generated by identity column, Do not have an identity column, make it a simple INT column.
If you want to remove the identity property from the column, you can do it by a cumbersome process of:
Inserting a new column
Updating its value
Dropping the original column
Then, if you want, you can basically repeat to get the original column name back. Something like this:
alter table Subject add SubjectId_new int;
update Subject set SubjectId_new = SubjectId;
alter table Subject drop SubjectId;
And then perhaps:
alter table Subject add SubjectId int;
update Subject set SubjectId = SubjectId_new;
alter table Subject drop SubjectId;
Or, just copy the data into a new table with the format that you want.
Switch off the identity
SET IDENTITY_INSERT [dbo].[Subject] ON
copy the record
insert into [dbo].[Subject] (subjectid,Name,version, createdby,createddate,modifiedby,modifiedDate) (select 0,Name,version, createdby,createddate,modifyby,nodifiedDate) from [dbo].[subject] where subjectid=2
Switch identity oFF
SET IDENTITY_INSERT [dbo].[Subject] ON