SQL Server 2000
Say if I have a table like
CREATE TABLE [Message] (
[MessageIdx] [int] IDENTITY (1, 1) NOT NULL ,
[Message] [varchar] (1024) COLLATE Latin1_General_CI_AS NOT NULL ,
[column1] ... ,
[column2] ... ,
... ,
[ValidUntil] [datetime] NULL ,
CONSTRAINT [PK_Message] PRIMARY KEY CLUSTERED
(
[MessageIdx]
) WITH FILLFACTOR = 90 ON [PRIMARY]
) ON [PRIMARY]
GO
Since there're too many columns, so I am trying to insert value without specify column names explicitly. I want to insert a new row with all columns except 'MessageIdx' and 'ValidUntil' not specified. Therefore, I definitely don't want to type all column names.
I tried below statement but it causes error. How can I do that? Thanks.
insert into message values (DEFAULT,'blah',something, ..., DEFAULT);
EDIT: AFAIN, SQL 2005 server you can skip the identity column when inserting. So that will be
insert into message values ('blah',something, ..., DEFAULT);
But is there any work around for SQL server 2000?
you have to specify column names if you use set identity_insert
but you can do this
set identity_insert caconfig..fxmessage on;
insert into message (MessageIdx,[Message],[ValidUntil)
values (1,'blah',GETDATE());
set identity_insert caconfig..fxmessage off;
I assume what you really want is this, it will generate the identity value for you
insert into message ([Message],[ValidUntil) values ('blah',GETDATE());
Don't be lazy. Do it the correct way, which is to specify the column list (excluding the identity column).
Use getdate(), and for IDENTITY columns (if using uniqueidentifier which I see you're not), you can use newid(), and set them in the design-view of the table in the default value. After that you'd simply go:
INSERT INTO Message (Message) VALUES ('blah');
Related
I'm attempting to build a table with the following code - No errors when I create the table, I can see the struncture and it shows that IDENTITY_INSERT is set to ON.
CREATE TABLE lt_percent_cs
(
id_key INT IDENTITY PRIMARY KEY,
customer_no INT ,
season INT,
percentage DECIMAL,
created_by VARCHAR(15) NULL,
create_dt DATETIME NULL,
last_updated_by VARCHAR(15) NULL,
last_update_dt DATETIME NULL,
create_loc VARCHAR(16) NULL
) ON [primary]
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].lt_percent_cs
ADD CONSTRAINT [lt_percent_created_by]
DEFAULT (user_name()) FOR [created_by]
GO
ALTER TABLE [dbo].lt_percent_cs
ADD CONSTRAINT [lt_percent_create_dt]
DEFAULT (getdate()) FOR [create_dt]
GO
ALTER TABLE [dbo].lt_percent_cs
ADD CONSTRAINT [lt_percent_create_loc]
DEFAULT [dbo].fs_location() FOR [create_loc]
GO
SET IDENTITY_INSERT lt_percent_cs ON
I get the following error when I attempt to insert data (through application not via code).
Last Error: Database update failed:
dataobject=
sqlca.sqlerrtext=SQLSTATE = 42000
Microsoft OLE DB Provider for SQL Server
Cannot insert explicit value for identity column in table 'lt_percent_cs' when IDENTITY_INSERT is set to OFF.
No changes made to database.
INSERT INTO lt_percent_cs (id_key, customer_no, season, percentage)
VALUES (54891, 80055514, 2017, 50)
sqlca.sqldbcode=544
sqlsyntax:
INSERT INTO lt_percent_cs (id_key, customer_no, season, percentage) VALUES (54891, 80055514, 2017, 50)
row:1 [nvo_ds_database.uf_update.34 (544)]
I should add when I run the script in SQL Server Management Studio, it works without issue and no errors are generated.
INSERT INTO lt_percent_cs (id_key, customer_no, season, percentage)
VALUES (54891, 80055514, 2017, 50)
Any thoughts?
Remove id_key from Insert statement since id_key is identity seeded
INSERT INTO lt_percent_cs (customer_no, season, percentage ) VALUES ( 80055514, 2017, 50 )
Otherwise declare id_key as integer Primary Key
then Insert should work
INSERT INTO lt_percent_cs ( id_key, customer_no, season, percentage ) VALUES ( 54891, 80055514, 2017, 50 )
Since you want bulk insert data and maintain the identity I can suggest alter id_key to integer primary key then bulk insert then alter field back to identity to ON... going forward you don't need to insert id_key
If you want to insert a explicit Id in application, you have to set Identity_insert on and insert in one transaction! I don't know, which application you are using, but this rule is universal.
I'm moving my configuration tables from Development environment to Test environment.
I'm using Identity as a primary key for the configuration tables.
Identity has option SET IDENTITY_INSERT [TABLE_NAME] [ON|OFF] that lets you insert values in the Identity column.
Here is an example for the same:
CREATE TABLE test_Identity (
[ID] int Identity (1,1),
[Product Name] nvarchar(50)
)
SET IDENTITY_INSERT test_Identity ON
INSERT test_Identity ([ID], [Product Name]) VALUES (1,'PRODUCT1')
SET IDENTITY_INSERT #test_Identity OFF
The above code lets me insert values specific values in the Identity column.
Now is there a way to insert specific values while using a SEQUENCE OBJECT in SQL Server?
Thanks in Advance !!!
There is no equivalent to identity_insert for sequences. Just insert the desired values normally.
A sequence is just tied to a column with a default constraint and supplies a default value if you don't override it.
There is nothing special about a column with a sequence default it is treated the same as any other column and can have explicit values inserted or be updated.
I am migrating my application form one database to other with keeping table structure as it is. I am creating same tables in new table and inserted value using db link.
I am getting error message like "Cannot insert explicit value for identity column in table 'XYZ' when IDENTITY_INSERT is set to OFF." because table XYZ have ScreenConfigSettingAccessId as an identity column
Below is the script I am using for creating table and inserting value
CREATE TABLE [dbo].[XYZ](
[ScreenConfigSettingAccessId] [int] IDENTITY(1,1) NOT NULL,
[APP_ID] [int] NOT NULL,
[ScreenConfigSettingId] [int] NOT NULL,
[RSRC_ID] [char](20) NOT NULL)
)
INSERT INTO [dbo].[XYX]
(
[ScreenConfigSettingAccessId] ,
[APP_ID] ,
[ScreenConfigSettingId] ,
[RSRC_ID]
)
SELECT
[ScreenConfigSettingAccessId] ,
[APP_ID] ,
[ScreenConfigSettingId] ,
[RSRC_ID]
FROM [olddatabase].[database name].[dbo].[XYX]
in old table the value of ScreenConfigSettingAccessId is 3 and 4.
I want to inset the same data which old table have so set IDENTITY_INSERT to ON and tried but it still not allowing to insert.
Looking for you suggestions
You need to specify the table. Check out the command syntax in SQL Books Online: SQL 2000 or SQL 2012 (the syntax hasn't changed).
I have created a linked server object in SQL management studio on our on premise SQL box and I can insert into it as following syntax:
insert into [Azure].[budget].dbo.Bill
I want to set identity insert and have tried the following:
SET IDENTITY_INSERT [Azure].[budget].dbo.Bill ON
insert into [Azure].[budget].dbo.Bill
This is yielding the error that there are too many prefixes. Why can I insert into it without the identity insert and is it possible to do this any other way?
I have then changed the identity insert part to be SP as follows:
EXEC [Azure].[budget].dbo.sp_executesql N'SET IDENTITY_INSERT Bill ON'
insert into [Azure].[budget].dbo.Bill
But I am getting a warning about not having permission on the BillID field
You can't use SET IDENTITY INSERT directly in linked server.
You need to use dynamic SQL to SET IDENTITY_INSERT ON
sp_executesql N'SET IDENTITY_INSERT [Azure].[budgetenergy].dbo.Bill ON;insert into [Azure].[budget].dbo.Bill ....';
You can INSERT an identity value into a table with an identity column on a linked server with the "SWITCH TO" trick.
If you haven't used the "SWITCH TO" trick to add and remove identity on a column, it's very quick, even on large tables!
Conceptually you simply create a new SCHEMA exactly like the table you are wanting to INSERT to without the identity defined. Then switch the table to that SCHEMA and do your INSERT. Then switch back to the SCHEMA with the identity defined.
The sample below has been tested on a linked server in AZURE.
All the caveats of using "SWITCH TO" apply (indexes must be the same, drop and recreate foreign keys, etc)
To test, you can run the full script below on an Linked Azure SQL Server database. You'll need to do a find/replace with [LINKED_SERVER_NAME] and [DATABASE_NAME], replacing with your values. On a non-Azure DB you may need to add "ON PRIMARY" to the table creations.
--Let's setup the example by creating a table with an IDENTITY column on the Linked Server
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nchar](10) NULL
)
'
) AT [LINKED_SERVER_NAME]
--INSERT some data into the table
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] ([Name]) VALUES ('Travis')
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] ([Name]) VALUES ('Jay')
-- Looks good
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
GO
-- Create a TABLE with an identical schema, without the identity defined
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table_temp](
[ID] [int] NOT NULL,
[Name] [nchar](10) NULL
)
'
) AT [LINKED_SERVER_NAME]
--Now Use the "SWITCH TO" to move the data to the new table
EXEC('
ALTER TABLE [DATABASE_NAME].[dbo].[Example_Table] SWITCH TO [DATABASE_NAME].[dbo].[Example_Table_temp]
'
) AT [LINKED_SERVER_NAME]
--Drop the old table (It should now be empty, but you may want to verify that if you are unsure here)
EXEC('
DROP TABLE [DATABASE_NAME].[dbo].[Example_Table]
'
) AT [LINKED_SERVER_NAME]
--Rename the new table back to the old table name
-- NOTE the lack of database and owner identifiers in the new name
-- NOTE the use of double single qoutes (ESCAPED single quotes)
EXEC('
EXEC sp_rename ''[DATABASE_NAME].[dbo].Example_Table_temp'',''Example_Table''
'
) AT [LINKED_SERVER_NAME]
-- Now do your IDENTITY INSERTs !!!!
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (888,'Travis')
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (999,'Jay')
--Verify they got put in
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
--Now let's switch it back to our SCHEMA with an IDENTITY
EXEC('
CREATE TABLE [DATABASE_NAME].[dbo].[Example_Table_temp](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [nchar](10) NULL
)
ALTER TABLE [DATABASE_NAME].[dbo].[Example_Table] SWITCH TO [DATABASE_NAME].[dbo].[Example_Table_temp]
DROP TABLE [DATABASE_NAME].[dbo].[Example_Table]
EXEC sp_rename ''[DATABASE_NAME].[dbo].Example_Table_temp'',''Example_Table''
'
) AT [LINKED_SERVER_NAME]
--Data is still there
SELECT * FROM [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table]
GO
-- And note you can no longer INSERT the IDENTITY
INSERT INTO [LINKED_SERVER_NAME].[DATABASE_NAME].[dbo].[Example_Table] (ID,[Name]) VALUES (45,'Travis')
GO
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