I'm trying to programmatically add an identity column to a table Employees. Not sure what I'm doing wrong with my syntax.
ALTER TABLE Employees
ADD COLUMN EmployeeID int NOT NULL IDENTITY (1, 1)
ALTER TABLE Employees ADD CONSTRAINT
PK_Employees PRIMARY KEY CLUSTERED
(
EmployeeID
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
What am I doing wrong? I tried to export the script, but SQL Mgmt Studio does a whole Temp Table rename thing.
UPDATE:
I think it is choking on the first statement with "Incorrect syntax near the keyword 'COLUMN'."
Just remove COLUMN from ADD COLUMN
ALTER TABLE Employees
ADD EmployeeID numeric NOT NULL IDENTITY (1, 1)
ALTER TABLE Employees ADD CONSTRAINT
PK_Employees PRIMARY KEY CLUSTERED
(
EmployeeID
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
This is how Adding new column to Table
ALTER TABLE [tableName]
ADD ColumnName Datatype
E.g
ALTER TABLE [Emp]
ADD Sr_No Int
And If you want to make it auto incremented
ALTER TABLE [Emp]
ADD Sr_No Int IDENTITY(1,1) NOT NULL
The correct syntax for adding column into table is:
ALTER TABLE table_name
ADD column_name column-definition;
In your case it will be:
ALTER TABLE Employees
ADD EmployeeID int NOT NULL IDENTITY (1, 1)
To add multiple columns use brackets:
ALTER TABLE table_name
ADD (column_1 column-definition,
column_2 column-definition,
...
column_n column_definition);
COLUMN keyword in SQL SERVER is used only for altering:
ALTER TABLE table_name
ALTER COLUMN column_name column_type;
It could be doing the temp table renaming if you are trying to add a column to the beginning of the table (as this is easier than altering the order). Also, if there is data in the Employees table, it has to do insert select * so it can calculate the EmployeeID.
Related
I have trouble in copying table data and structure to another table since I want to keep the Id column of Identity column and keep its oridinal value instead of starting from 1
I use below sql to insert all data except the ID column from MY_TABLE to MY_TABLE_NEW since it has error saying that
Only when the column list is used and IDENTITY_INSERT is ON, an explicit value can be specified for the identity column in the table'My_TABLE_NEW'.
But I have set it like below SQL:
IF NOT EXISTS (select * from sys.objects where name = 'My_TABLE_NEW')
BEGIN
CREATE TABLE [dbo].[My_TABLE_NEW]
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[OBJECT_ID] [int] NOT NULL,
[YEAR_MONTH] [int] NOT NULL,
CONSTRAINT [PK_My_TABLE_NEW]
PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
IF EXISTS (SELECT * FROM sys.objects WHERE name = 'My_TABLE_NEW')
BEGIN
SET IDENTITY_INSERT My_TABLE_NEW ON
INSERT INTO My_TABLE_NEW
SELECT [ID]
,[OBJECT_ID]
,[YEAR_MONTH]
FROM My_TABLE
SET IDENTITY_INSERT My_TABLE_NEW OFF
END
GO
What is the problem?
Try your insert with the column names:
INSERT INTO My_TABLE_NEW ([ID], [OBJECT_ID], [YEAR_MONTH])
SELECT [ID]
,[OBJECT_ID]
,[YEAR_MONTH]
FROM My_TABLE
From the documentation:
When an existing identity column is selected into a new table, the new column inherits the IDENTITY property, unless one of the following conditions is true:
The SELECT statement contains a join, GROUP BY clause, or aggregate function.
Multiple SELECT statements are joined by using UNION.
The identity column is listed more than one time in the select list.
The identity column is part of an expression.
The identity column is from a remote data source.
That means you can copy the table with SELECT INTO while retaining the identity column and can just add the PK after.
SELECT *
INTO My_TABLE_NEW
FROM My_TABLE
Here is a demo with fiddle.
You can use the built-in tool sp_rename for this, as long as you are just renaming the table not trying to create a copy of it.
EXEC sp_rename 'My_TABLE', 'My_TABLE_NEW'
GO;
https://learn.microsoft.com/en-us/sql/relational-databases/system-stored-procedures/sp-rename-transact-sql?view=sql-server-ver15
If you want to create a copy, then you just have to do the following:
SELECT *
INTO My_TABLE_NEW
FROM My_TABLE
Note: If you do this, you will have to re-add any key constraints, computed value columns, etc.
I have a a table with about 10000 records and an identity column that doesn't do auto increment, I want to change this. Normally I would drop the column and re-add it with the identity on but the problem is that this column is used as a foreign key in a lot of my other tables and there are some numbers in the primary column that are missing. I know that I cant change the column to start auto incrementing but is there a way to have the new auto incremented column copy the same numbers as the original and start from the end of that?
You should be able to do something like below. Table_1 is the table I wish to update to now include an identity column whereas the column was just a simple int before. Notice when it is creating the tmp_Table_1 it is creating an identity column that is setting the identity seed to 889 since the largest int id i had before was 888. The script then takes all the data in the existing table and inserts into into the tmp table, then drops the old table and renames the tmp table back to Table_1. By setting the identity seed to 889 the next row of data you insert will insert with an id of 890 automatically. Does this make sense?
BEGIN TRANSACTION
GO
CREATE TABLE dbo.Tmp_Table_1
(
id int NOT NULL IDENTITY (889, 1),
name nchar(10) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_Table_1 SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_Table_1 ON
GO
IF EXISTS(SELECT * FROM dbo.Table_1)
EXEC('INSERT INTO dbo.Tmp_Table_1 (id, name)
SELECT id, name FROM dbo.Table_1 WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_Table_1 OFF
GO
DROP TABLE dbo.Table_1
GO
EXECUTE sp_rename N'dbo.Tmp_Table_1', N'Table_1', 'OBJECT'
GO
ALTER TABLE dbo.Table_1 ADD CONSTRAINT
PK_Table_1 PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
Is it possible to just create a table in MSSQL without columns?
I'm asking this because I'll have to check for every columns if it already exists or not.
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tags]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].Tags(
[Id] [int] IDENTITY(1,1) NOT NULL,
CONSTRAINT [PK_Tags] PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
END
GO
The execution might break by creating the column Id if the table and the column already exists.
This would be ideally:
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tags]') AND type in (N'U'))
CREATE TABLE [dbo].Tags
GO
if NOT EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'Tags' and column_name = 'Id')
alter table MyTable add MyColumn int IDENTITY(1,1) NOT NULL
GO
-- add new primary key constraint on new column
ALTER TABLE dbo.Tags
ADD CONSTRAINT PK_Tags
PRIMARY KEY CLUSTERED ([Id] ASC)
GO
I can't find an example on the second piece of code. But I can imagine that a table can't be created with 0 columns.
Any suggestions?
[Edit]
Some more context. Some tables exists some don't. Some columns exists some don't. I want to creat a script which could be executed anytime without breaking or causing error msg's like the table/column already exists.
This code
create table tab
raises an error
Incorrect syntax near 'tab'.
and this code
create table tab1
(
id int
)
alter table tab1 drop id
raises an error
ALTER TABLE 'tab1' failed. Dropping all columns in a table is not
allowed.
so a table without columns is not possible.
I think you can acheive what you're trying using the following:
Create the table with the ID and only check for the existence of the Id column if you didn't have to create the table.
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Tags]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].Tags (Id int IDENTITY(1,1) NOT NULL)
END
ELSE
BEGIN
if NOT EXISTS (select column_name from INFORMATION_SCHEMA.columns where table_name = 'Tags' and column_name = 'Id')
BEGIN
alter table [dbo].Tags add MyColumn int IDENTITY(1,1) NOT NULL
-- add new primary key constraint on new column
ALTER TABLE dbo.Tags
ADD CONSTRAINT PK_Tags
PRIMARY KEY CLUSTERED ([Id] ASC)
END
ELSE
GO
Of course you can't create table without columns in SQL Server, but if the table doesn't exist before you create it, it doesn't have any column, so why don't you simply create it?
If this is a kind of upgrade script you might do an ELSE branch where you check for each column before adding it.
i have this sql table
CREATE TABLE Notes(
NoteID [int] IDENTITY(1,1) NOT NULL,
NoteTitle [nvarchar](255) NULL,
NoteDescription [nvarchar](4000) NULL
) CONSTRAINT [PK_Notes] PRIMARY KEY CLUSTERED
(
NoteID ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
And i want to copy records from a temporary table INCLUDING the NoteID(using sql query)..
this is my script:
SET IDENTITY_INSERT Notes OFF
INSERT INTO Notes (NoteID, NoteTitle,NoteDescription)
SELECT NoteID, NoteTitle,NoteDescription from Notes_Temp
SET IDENTITY_INSERT Notes ON
with this script, i'm getting an error:
Cannot insert explicit value for identity column in table 'Notes' when IDENTITY_INSERT is set to OFF.
is there other way of insert records to a table with identity column using sql query?
Change the OFF and ON around
SET IDENTITY_INSERT Notes ON
INSERT INTO Notes (NoteID, NoteTitle,NoteDescription)
SELECT NoteID, NoteTitle,NoteDescription from Notes_Temp
SET IDENTITY_INSERT Notes OFF
SET IDENTITY_INSERT Notes ON
INSERT INTO Notes
/*Note the column list is REQUIRED here, not optional*/
(NoteID, NoteTitle,NoteDescription)
SELECT NoteID, NoteTitle,NoteDescription from Notes_Temp
SET IDENTITY_INSERT Notes OFF
You're inserting values for NoteId that is an identity column.
You can turn on identity insert on the table like this so that you can specify your own identity values.
Presumably you are using SQL Server (you don't say) and have misunderstood the meaning and purpose of IDENTITY_INSERT. In general, you are not allowed to explicitly set the value of an IDENTITY column, but by setting IDENTITY_INSERT to ON for a table you can temporarily permit such inserts.
I have the following SQL command:
ALTER TABLE dbo.UserProfiles
ADD ChatId UniqueIdentifier NOT NULL,
UNIQUE(ChatId),
CONSTRAINT "ChatId_default" SET DEFAULT newid()
I want to be able to make this column unique, and I want it to be able to generate a new guid every time a row is added to the table. This column is not an IDENTITY column because I already have one. This is something separate. How would I go about adding this column to a table with users already in it.
see this sample:
create table test (mycol UniqueIdentifier NOT NULL default newid(), name varchar(100))
insert into test (name) values ('Roger Medeiros')
select * from test
for add a not null field on a populated table you need this.
alter table test add mycol2 UniqueIdentifier NOT NULL default newid() with values
CREATE UNIQUE NONCLUSTERED INDEX IX_test ON dbo.test
(
mycol
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Don't use newid() as default, instead use newsequentialid(). newid() creates a lot of fragmentation and that's bad for indexes.
As far as adding the new column to a table with existing data, simply do this:
ALTER TABLE your_table
ADD your_column UNIQUEIDENTIFIER DEFAULT newsequentialid() NOT null