IDENTITY vs SEQUENCE OBJECT IN SQLSERVER - sql-server

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.

Related

is it possible that an auto increment field duplicates?

I have a table which has several field including:
contact_id
phone
phone_id
contact_id and phone are primary keys and phone_id is an auto increment field. I want to use it to recognize a certain entry. So I want to know that is it possible to duplicate that non primary field when I'm entering data.
Unless there is no constraint, some unique index, you can duplicate values in that column, because 1) you can turn identity_insert on, 2) you can reseed increments.
Here is a proof:
CREATE TABLE #test(id INT IDENTITY(1, 1))
INSERT INTO #test DEFAULT VALUES
INSERT INTO #test DEFAULT VALUES
INSERT INTO #test DEFAULT VALUES
SET IDENTITY_INSERT #test ON
INSERT INTO #test(id) VALUES(1)
SET IDENTITY_INSERT #test OFF
INSERT INTO #test DEFAULT VALUES
INSERT INTO #test DEFAULT VALUES
DBCC CHECKIDENT ('#test', RESEED, 1);
INSERT INTO #test DEFAULT VALUES
INSERT INTO #test DEFAULT VALUES
SELECT * FROM #test
DROP TABLE #test
Output:
id
1
2
3
1
4
5
2
3
The short answer is Yes, it's possible.
SQL Server does not force a unique constraint on identity columns, meaning that the can have duplicated values, however, Sql server will not generate duplicate values itself in an identity column.
Identity columns in sql server are populated by the sql server itself when you insert a row to the table.
However, you can specify a value to them by using SET IDENTITY_INSERT before the insert statement.
There are a couple of things that you should be aware of:
Setting identity_insert on is per table. you can only set it for one table at the time.
Until you set the identity_insert back off, any insert statement to that table will have to specify a value for the identity column.
you can't use set identity insert on for more then one table on a single session. therefor after you've done inserting records to the table you must set the identity_insert back off on that table.

Insert a new row in an SQL table without assigning any values

I have an SSMS table that has one column that is a pk and set to auto increment. In my code I need to create a row and then pull the value of the ID.
I don't want to set the id, it needs to auto generate. Is there a way to do this without adding a second column to add data into?
Just use the phrase "DEFAULT VALUES" in place of a field list and values specification:
INSERT INTO [TableName] DEFAULT VALUES;
Test with:
CREATE TABLE #Test
(
ID INT IDENTITY(1, 1) NOT NULL PRIMARY KEY
);
INSERT INTO #Test DEFAULT VALUES;
SELECT SCOPE_IDENTITY();
For more info on this, check out the MSDN page for INSERT and do a "find" (i.e. Control-F) in your browser for "default values".

How can I turn off identity and insert into a row in SQL Server 2012?

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

Preventing specifying values in a column

Is there a way to prevent specifying explicit values in a column? The identity attribute prevents specifying explicit values (as long as IDENTITY_INSERT is off), which is the type of behavior I want.
create table testguid (
ID uniqueidentifier default newsequentialid() not null primary key
,somedate datetime
)
[constraint or trigger here?]
insert into testguid (somedate) values (getdate()) -- this is ok
insert into testguid (ID, somedate) values (newid(), getdate()) -- this is not ok
I want the database to insert values, but I want to prevent any way of specifying them.
You could use an INSTEAD OF TRIGGER to basically re-write the INSERT statement, leaving out the ID column.
CREATE TRIGGER dbo.testguid_beforeinsert
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.testguid(somedate --, other columns
) SELECT GETDATE() --, other columns
FROM inserted;
END
GO
Probably want something similar for UPDATE, too.

SQL insert default value

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');

Resources