How to turn IDENTITY_INSERT on and off using SQL Server 2008? - sql

Why am I getting an error doing an insert when IDENTITY_INSERT is set to OFF?
How do I turn it on properly in SQL Server 2008? Is it by using SQL Server Management Studio?
I have run this query:
SET IDENTITY_INSERT Database. dbo. Baskets ON
Then I got the message back in the console that the Command(s) completed successfully.
However when I run the application, it still gives me the error shown below:
Cannot insert explicit value for identity column in table 'Baskets' when
IDENTITY_INSERT is set to OFF.

Via SQL as per MSDN
SET IDENTITY_INSERT sometableWithIdentity ON
INSERT INTO sometableWithIdentity
(IdentityColumn, col2, col3, ...)
VALUES
(AnIdentityValue, col2value, col3value, ...)
SET IDENTITY_INSERT sometableWithIdentity OFF
The complete error message tells you exactly what is wrong...
Cannot insert explicit value for identity column in table 'sometableWithIdentity' when IDENTITY_INSERT is set to OFF.

I had a problem where it did not allow me to insert it even after setting the IDENTITY_INSERT ON.
The problem was that i did not specify the column names and for some reason it did not like it.
INSERT INTO tbl Values(vals)
So basically do the full INSERT INTO tbl(cols) Values(vals)

Import:
You must write columns in INSERT statement
INSERT INTO TABLE
SELECT * FROM
Is not correct.
Insert into Table(Field1,...)
Select (Field1,...) from TABLE
Is correct

I know this is an older thread but I just bumped into this. If the user is trying to run inserts on the Identity column after some other session Set IDENTITY_INSERT ON, then he is bound to get the above error.
Setting the Identity Insert value and the subsequent Insert DML commands are to be run by the same session.
Here #Beginner was setting Identity Insert ON separately and then running the inserts from his application. That is why he got the below Error:
Cannot insert explicit value for identity column in table 'Baskets' when
IDENTITY_INSERT is set to OFF.

It looks necessary to put a SET IDENTITY_INSERT Database.dbo.Baskets ON; before every SQL INSERT sending batch.
You can send several INSERT ... VALUES ... commands started with one SET IDENTITY_INSERT ... ON; string at the beginning. Just don't put any batch separator between.
I don't know why the SET IDENTITY_INSERT ... ON stops working after the sending block (for ex.: .ExecuteNonQuery() in C#). I had to put SET IDENTITY_INSERT ... ON; again at the beginning of next SQL command string.

This is likely when you have a PRIMARY KEY field and you are inserting a value that is duplicating or you have the INSERT_IDENTITY flag set to on

Another option is where you have tables like 'type' or 'status', for example, OrderStatus, where you always want to control the Id value, create the Id (Primary Key) column without it being an Identity column is the first place.

Related

My first question — Violation of PRIMARY KEY constraint

I have the following issue: I want to execute a script where I'm trying to insert data from a database that I restored (iNode-8-24-14-Orig) into a database that I created.
The code is:
/****************************************************/
SET IDENTITY_INSERT [dbo].[XHQ_HIER_DEF] ON;
GO
INSERT INTO [dbo].[XHQ_HIER_DEF]
([HIER_KEY]
,[HIER_NAME]
,[HIER_DESC]
,[SYNONYM_DEF_LEVEL]
,[CRT_XHQUSERID]
,[CRT_TIMESTAMP]
,[CRT_TZ_BIAS]
,[UPDT_XHQUSERID]
,[UPDT_TIMESTAMP]
,[UPDT_TZ_BIAS])
SELECT [HIER_KEY]
,[HIER_NAME]
,[HIER_DESC]
,[SYNONYM_DEF_LEVEL]
,[CRT_XHQUSERID]
,[CRT_TIMESTAMP]
,[CRT_TZ_BIAS]
,[UPDT_XHQUSERID]
,[UPDT_TIMESTAMP]
,[UPDT_TZ_BIAS]
FROM [iNode-8-24-14-Orig].[dbo].[XHQ_HIER_DEF]
GO
SET IDENTITY_INSERT [dbo].[XHQ_HIER_DEF] OFF;
GO
/****************************************************/
But I get this error for each table:
Violation of PRIMARY KEY constraint 'XPKXHQ_HIER_DEF'. Cannot insert
duplicate key in object 'dbo.XHQ_HIER_DEF'. The duplicate key value is
(1).
Any idea how can I fix this? I want to mention that I have the same tables and columns in both databases. I know is saying that I'm already using the same primary key, but I don't know how to fix it.
This is my first question on this site.
And we care... why?
Any idea how can i fix this?
Read the error, fix the data? The error says very clear what the issue is:
Cannot insert duplicate key in object 'dbo.XHQ_HIER_DEF'.
Do not insert the same key value multiple times. Period. If you define a field as primary key, values have per definition to be unique in the key.
There already is an entry with identity 1, or your source data has multiple rows with the same value, which is not valid per your data model.
Generally for problems like this, actually reading the error helps. In your case it is EXTREMELY clear in the description what the issue is, even giving you the value causing the problem:
The duplicate key value is (1).
Solution is obvious: do not insert duplicate primary key values.
From your I suppose:
You're using MSSQL with linked server
PK consists of HIER_KEY field only
So:
/****************************************************/
SET IDENTITY_INSERT [dbo].[XHQ_HIER_DEF] ON;
GO
INSERT INTO [dbo].[XHQ_HIER_DEF]
([HIER_KEY]
,[HIER_NAME]
,[HIER_DESC]
,[SYNONYM_DEF_LEVEL]
,[CRT_XHQUSERID]
,[CRT_TIMESTAMP]
,[CRT_TZ_BIAS]
,[UPDT_XHQUSERID]
,[UPDT_TIMESTAMP]
,[UPDT_TZ_BIAS])
SELECT [HIER_KEY]
,[HIER_NAME]
,[HIER_DESC]
,[SYNONYM_DEF_LEVEL]
,[CRT_XHQUSERID]
,[CRT_TIMESTAMP]
,[CRT_TZ_BIAS]
,[UPDT_XHQUSERID]
,[UPDT_TIMESTAMP]
,[UPDT_TZ_BIAS]
FROM [iNode-8-24-14-Orig].[dbo].[XHQ_HIER_DEF] T1
WHERE NOT EXISTS(
SELECT 1 FROM [dbo].[XHQ_HIER_DEF] T2
WHERE
T1.HIER_KEY = T2.HIER_KEY
)
GO
SET IDENTITY_INSERT [dbo].[XHQ_HIER_DEF] OFF;
GO
/****************************************************/
Warning: performance of such insert could be especially terrible.

Inserting values when identity is on

I have a table with identity(1,1) field and i want to use insert into to insert values into it.
How can I insert values into the indentity field?
Thank you!
SET IDENTITY_INSERT tbl ON
-- insert (include the ID column)
SET IDENTITY_INSERT tbl OFF
you've got to do this:
SET IDENTITY_INSERT TableNameHere ON
then you can insert values into it:
SET IDENTITY_INSERT IdentityTable ON
INSERT IdentityTable(TheIdentity, TheValue)
VALUES (3, 'First Row')
SET IDENTITY_INSERT IdentityTable OFF
If your question is actually how you get the system to supply appropriate values in the identity column, the answer is that you just don't mention it in your insert query:
INSERT INTO Table (ColumnA_That_Isnt_Identity,ColumnB_That_Isnt_Identity)
VALUES (9,'abc')
And then the IDENTITY column will be assigned a value automatically.
If you want to know what value was assigned to this column, you can either query SCOPE_IDENTITY as a separate SELECT or include an OUTPUT clause, as here:
INSERT INTO Table (ColumnA_That_Isnt_Identity,ColumnB_That_Isnt_Identity)
OUTPUT inserted.ID_Column_That_Is_The_Identity
VALUES (9,'abc')
When IDENTITY_INSERT is ON, you're telling the system "trust me, I'll supply an appropriate value". When it's OFF, you're telling the system to supply the value. Those are your two choices.
There's no means to, on the one had, set IDENTITY_INSERT as ON, and, whilst that is set, request that the system provide a value. Given that IDENTITY_INSERT has only a single purpose, to allow you to provide the values, this should never be a problem.

IDENTITY_INSERT error while trying to insert data into table

I want to copy data from a table named ActionType inside a database TD_EDD, into another table named ActionType inside another database DsVelocity.
I have written the following query:
INSERT INTO [DsVelocity].[dbo].[ActionType]
([ActionTypeID]
,[ActionTypeName]
,[ActiveStatus])
SELECT [ActionTypeID], [ActionType], [Active/Deactive]
FROM [TD_EDD].[dbo].[ActionType]
GO
Whenever I'm trying to do this, I'm getting the following error:
Msg 544, Level 16, State 1, Line 1
Cannot insert explicit value for identity column in table 'ActionType' when IDENTITY_INSERT is set to OFF.
I don't understand what's wrong and why I'm getting this error?
Note that I'm using Microsoft SQL Server 2008 R2.
This means that when you insert data into target table, you will have conflicting ids. Most likely ActionTypeId column
to Fix it use
INSERT INTO [DsVelocity].[dbo].[ActionType]
([ActionTypeName]
,[ActiveStatus])
SELECT [ActionType], [Active/Deactive]
FROM [TD_EDD].[dbo].[ActionType]
GO
Well, lets assume from the message that ActionTypeID is an IDENTITY Column. You cannot isert values into this column as it is auto generate, uless you use IDENTITY_INSERT
Allows explicit values to be inserted into the identity column of a
table.
At any time, only one table in a session can have the IDENTITY_INSERT
property set to ON. If a table already has this property set to ON,
and a SET IDENTITY_INSERT ON statement is issued for another table,
SQL Server returns an error message that states SET IDENTITY_INSERT is
already ON and reports the table it is set ON for.
If the value inserted is larger than the current identity value for
the table, SQL Server automatically uses the new inserted value as the
current identity value.
The setting of SET IDENTITY_INSERT is set at execute or run time and
not at parse time.
So you would have to do something like
SET IDENTITY_INSERT [DsVelocity].[dbo].[ActionType] ON
before the insert.

IDENTITY_INSERT ON fails with error "...is not a user table. Cannot perform SET operation"

I've accidentally deleted a row in a database and I would like to reinsert the row. The problem is that the primary key is set to auto increment and IDENTITY INSERT is set to OFF for the table. I would like to temporarily enable identity insert so I can insert the deleted row, then disable identity insert.
In SQL Server Management Studio I attempted the following:
SET IDENTITY_INSERT myTable ON
INSERT INTO myTable (id, name, value)
VALUES (241, 'hello', 'hello2')
SET IDENTITY_INSERT myTable OFF
The first line fails out with this:
Msg 8105, Level 16, State 1, Line 2
'myTable' is not a user table. Cannot perform SET operation.
Any idea why?
Error description:
http://www.sql-server-performance.com/2007/not-a-user-table-cannot-perform-set-operation/
myTable doesn't appear to really be a table.
Try this:
SELECT * FROM sysobjects WHERE name = ‘myTable’
What is the xtype?

Help with SQL Server Trigger to truncate bad data before insert

We consume a web service that decided to alter the max length of a field from 255. We have a legacy vendor table on our end that is still capped at 255. We are hoping to use a trigger to address this issue temporarily until we can implement a more business-friendly solution in our next iteration.
Here's what I started with:
CREATE TRIGGER [mySchema].[TruncDescription]
ON [mySchema].[myTable]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [mySchema].[myTable]
SELECT SubType, type, substring(description, 1, 255)
FROM inserted
END
However, when I try to insert on myTable, I get the error:
String or binary data would be
truncated. The statement has been
terminated.
I tried experimenting with SET ANSI_WARNINGS OFF which allowed the query to work but then simply didn't insert any data into the description column.
Is there any way to use a trigger to truncate the too-long data or is there another alternative that I can use until a more eloquent solution can be designed? We are fairly limited in table modifications (i.e. we can't) because it's a vendor table, and we don't control the web service we're consuming so we can't ask them to fix it either. Any help would be appreciated.
The error cannot be avoided because the error is happening when the inserted table is populated.
From the documentation:
http://msdn.microsoft.com/en-us/library/ms191300.aspx
"The format of the inserted and deleted tables is the same as the format of the table on which the INSTEAD OF trigger is defined. Each column in the inserted and deleted tables maps directly to a column in the base table."
The only really "clever" idea I can think of is to take advantage of schemas and the default schema used by a login. If you can get the login that the web service is using to reference another table, you can increase the column size on that table and use the INSTEAD OF INSERT trigger to perform the INSERT into the vendor table. A variation of this is to create the table in a different database and set the default database for the web service login.
CREATE TRIGGER [myDB].[mySchema].[TruncDescription]
ON [myDB].[mySchema].[myTable]
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [VendorDB].[VendorSchema].[VendorTable]
SELECT SubType, type, substring(description, 1, 255)
FROM inserted
END
With this setup everything works OK for me.
Not to state the obvious but are you sure there is data in the description field when you are testing? It is possible they change one of the other fields you are inserting as well and maybe one of those is throwing the error?
CREATE TABLE [dbo].[DataPlay](
[Data] [nvarchar](255) NULL
) ON [PRIMARY]
GO
and a trigger like this
Create TRIGGER updT ON DataPlay
Instead of Insert
AS
BEGIN
SET NOCOUNT ON;
INSERT INTO [tempdb].[dbo].[DataPlay]
([Data])
(Select substring(Data, 1, 255) from inserted)
END
GO
then inserting with
Declare #d as nvarchar(max)
Select #d = REPLICATE('a', 500)
SET ANSI_WARNINGS OFF
INSERT INTO [tempdb].[dbo].[DataPlay]
([Data])
VALUES
(#d)
GO
I am unable to reproduce this issue on SQL 2008 R2 using:
Declare #table table ( fielda varchar(10) )
Insert Into #table ( fielda )
Values ( Substring('12345678901234567890', 1, 10) )
Please make sure that your field is really defined as varchar(255).
I also strongly suggest you use an Insert statement with an explicit field list. While your Insert is syntactically correct, you really should be using an explicit field list (like in my sample). The problem is when you don't specify a field list you are at the mercy of SQL and the table definition for the field order. When you do use a field list you can change the order of the fields in the table (or add new fields in the middle) and not care about your insert statements.