SQL query not executing as whole - sql

So I have a query that should add Primary Key to the Id field:
IF NOT EXISTS(SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = 'CAL')
BEGIN
DROP INDEX IF EXISTS CAL$01 ON dbo.CAL;
ALTER TABLE BTS.dbo.CAL
ALTER COLUMN Intern INT NOT NULL;
ALTER TABLE BTS.dbo.CAL
ADD CONSTRAINT PK_CAL_Intern PRIMARY KEY (Intern);
CREATE INDEX CAL$01
ON CAL (Intern);
END
The problem is that when I chose all this code and execute (F5), I get this error:
Whereas when I'm choosing every statement one by one it works as expected:
I am sure that the IF works as expected
I tried to use GO between statements, it's not allowed.
I should execute this code on a large number of tables
Maybe I don't know something about how SQL Server Management Studio executes statements

Before a query is run it is parsed. This is why what you're doing is failing. SQL server is checking the details of the Intern before the script is run. At the point you start to try to run the script, Intern in the table BTS.dbo.CAL is NULLable, and so the script fails.
You can get around this by running the statement to create the primary key cosntraint in a separate scope:
IF NOT EXISTS(
SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = 'CAL'
)
BEGIN
DROP INDEX IF EXISTS CAL$01 ON dbo.CAL;
ALTER TABLE
BTS.dbo.CAL
ALTER COLUMN
Intern
INT NOT NULL;
EXEC sys.sp_executesql N'ALTER TABLE BTS.dbo.CAL ADD CONSTRAINT PK_CAL_Intern PRIMARY KEY (Intern);';
CREATE INDEX [CAL$01]
ON CAL (Intern);
END'

Even though question is answer, I just wanted to add one more option.
You can separate statments into two separate batches, so that your change is available to the subsequent batch
CREATE TABLE #test(a int null);
-- DDL Changes
if exists(SELECT 1)
BEGIN
ALTER TABLE #test ALTER COLUMN a int not null;
END
GO
-- Index changes
if exists(SELECT 1)
BEGIN
ALTER TABLE #test ADD CONSTRAINT PK_test PRIMARY KEY(a)
END
GO

Related

Changing column Datatype from date to datetime without removing existing values in MSSql and Oracle sql server [duplicate]

I am trying to do this:
ALTER TABLE CompanyTransactions DROP COLUMN Created
But I get this:
Msg 5074, Level 16, State 1, Line 2
The object 'DF__CompanyTr__Creat__0CDAE408' is dependent on column 'Created'.
Msg 4922, Level 16, State 9, Line 2
ALTER TABLE DROP COLUMN Created failed because one or more objects access this column.
This is a code first table. Somehow the migrations have become all messed up and I am trying to manually roll back some changed.
I have no idea what this is:
DF__CompanyTr__Creat__0CDAE408
You must remove the constraints from the column before removing the column. The name you are referencing is a default constraint.
e.g.
alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];
alter table CompanyTransactions drop column [Created];
The #SqlZim's answer is correct but just to explain why this possibly have happened. I've had similar issue and this was caused by very innocent thing: adding default value to a column
ALTER TABLE MySchema.MyTable ADD
MyColumn int DEFAULT NULL;
But in the realm of MS SQL Server a default value on a colum is a CONSTRAINT. And like every constraint it has an identifier. And you cannot drop a column if it is used in a CONSTRAINT.
So what you can actually do avoid this kind of problems is always give your default constraints a explicit name, for example:
ALTER TABLE MySchema.MyTable ADD
MyColumn int NULL,
CONSTRAINT DF_MyTable_MyColumn DEFAULT NULL FOR MyColumn;
You'll still have to drop the constraint before dropping the column, but you will at least know its name up front.
As already written in answers you need to drop constraints (created automatically by sql) related to all columns that you are trying to delete.
Perform followings steps to do the needful.
Get Name of all Constraints using sp_helpconstraint which is a system stored procedure utility - execute following exec sp_helpconstraint '<your table name>'
Once you get the name of the constraint then copy that constraint name and execute next statement i.e alter table <your_table_name>
drop constraint <constraint_name_that_you_copied_in_1> (It'll be something like this only or similar format)
Once you delete the constraint then you can delete 1 or more columns by using conventional method i.e Alter table <YourTableName> Drop column column1, column2 etc
When you alter column datatype you need to change constraint key for every database
alter table CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];
You need to do a few things:
You first need to check if the constrain exits in the information schema
then you need to query by joining the sys.default_constraints and sys.columns
if the columns and default_constraints have the same object ids
When you join in step 2, you would get the constraint name from default_constraints. You drop that constraint. Here is an example of one such drops I did.
-- 1. Remove constraint and drop column
IF EXISTS(SELECT *
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = N'TABLE_NAME'
AND COLUMN_NAME = N'LOWER_LIMIT')
BEGIN
DECLARE #sql NVARCHAR(MAX)
WHILE 1=1
BEGIN
SELECT TOP 1 #sql = N'alter table [TABLE_NAME] drop constraint ['+dc.name+N']'
FROM sys.default_constraints dc
JOIN sys.columns c
ON c.default_object_id = dc.object_id
WHERE dc.parent_object_id = OBJECT_ID('[TABLE_NAME]') AND c.name = N'LOWER_LIMIT'
IF ##ROWCOUNT = 0
BEGIN
PRINT 'DELETED Constraint on column LOWER_LIMIT'
BREAK
END
EXEC (#sql)
END;
ALTER TABLE TABLE_NAME DROP COLUMN LOWER_LIMIT;
PRINT 'DELETED column LOWER_LIMIT'
END
ELSE
PRINT 'Column LOWER_LIMIT does not exist'
GO
In addition to accepted answer, if you're using Entity Migrations for updating database, you should add this line at the beggining of the Up() function in your migration file:
Sql("alter table dbo.CompanyTransactions drop constraint [df__CompanyTr__Creat__0cdae408];");
You can find the constraint name in the error at nuget packet manager console which starts with FK_dbo.
I had the same problem and this was the script that worked for me with a table with a two part name separated by a period ".".
USE [DATABASENAME]
GO
ALTER TABLE [TableNamePart1].[TableNamePart2] DROP CONSTRAINT [DF__ TableNamePart1D__ColumnName__5AEE82B9]
GO
ALTER TABLE [TableNamePart1].[ TableNamePart1] DROP COLUMN [ColumnName]
GO
I needed to replace an INT primary key with a Guid. After a few failed attempts, the EF code below worked for me. If you hyst set the defaultValue... you end up with a single Guid a the key for existing records.
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropUniqueConstraint("PK_Payments", "Payments");
migrationBuilder.DropColumn(
name: "PaymentId",
table: "Payments");
migrationBuilder.AddColumn<Guid>(
name: "PaymentId",
table: "Payments",
type: "uniqueidentifier",
defaultValueSql: "NewId()",
nullable: false);
}
Copy the default constraint name from the error message and type it in the same way as the column you want to delete.
I had the same problem, I could not remove migrations, it would show error that something is already applied, so i changed my DB name in appsettings, removed all migrations, and then added new migration and it worked. Dont understand issue completely, but it worked
I fixed by Adding Dropping constraint inside migration.
migrationBuilder.DropForeignKey(
name: "FK_XX",
table: "TableX").
and below recreates constraint.
migrationBuilder.AddForeignKey(
name: "FK_XX",
table: "TableX",
column: "ColumnX",
onDelete: ReferentialAction.Restrict);

Is Identity set to "No" in a Table [duplicate]

We have a 5GB table (nearly 500 million rows) and we want to remove the identity property on one of the column, but when we try to do this through SSMS - it times out.
Can this be done through T-SQL?
You cannot remove an IDENTITY specification once set.
To remove the entire column:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
Information about ALTER TABLE here
If you need to keep the data, but remove the IDENTITY column, you will need to:
Create a new column
Transfer the data from the existing IDENTITY column to the new column
Drop the existing IDENTITY column.
Rename the new column to the original column name
If you want to do this without adding and populating a new column, without reordering the columns, and with almost no downtime because no data is changing on the table, let's do some magic with partitioning functionality (but since no partitions are used you don't need Enterprise edition):
Remove all foreign keys that point to this table
Script the table to be created; rename everything e.g. 'MyTable2', 'MyIndex2', etc.
Remove the IDENTITY specification.
You should now have two "identical"-ish tables, one full, the other empty with no IDENTITY.
Run ALTER TABLE [Original] SWITCH TO [Original2]
Now your original table will be empty and the new one will have the data. You have switched the metadata for the two tables (instant).
Drop the original (now-empty table), exec sys.sp_rename to rename the various schema objects back to the original names, and then you can recreate your foreign keys.
For example, given:
CREATE TABLE Original
(
Id INT IDENTITY PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value ON Original (Value);
INSERT INTO Original
SELECT 'abcd'
UNION ALL
SELECT 'defg';
You can do the following:
--create new table with no IDENTITY
CREATE TABLE Original2
(
Id INT PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value2 ON Original2 (Value);
--data before switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
ALTER TABLE Original SWITCH TO Original2;
--data after switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
--clean up
IF NOT EXISTS (SELECT * FROM Original) DROP TABLE Original;
EXEC sys.sp_rename 'Original2.IX_Original_Value2', 'IX_Original_Value', 'INDEX';
EXEC sys.sp_rename 'Original2', 'Original', 'OBJECT';
UPDATE Original
SET Id = Id + 1;
SELECT *
FROM Original;
For the record, as this has become increasingly popular, I have wanted to track down the original source (I didn't think of it myself), but of course I've long forgotten where I found the original idea. It may have been here; this was the only one I could find predating this answer (time flies, boys and girls): https://social.technet.microsoft.com/wiki/contents/articles/17738.sql-server-quick-way-to-remove-the-identity-property.aspx
This gets messy with foreign and primary key constraints, so here's some scripts to help you on your way:
First, create a duplicate column with a temporary name:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
Next, get the name of your primary key constraint:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
Now try drop the primary key constraint for your column:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
If you have foreign keys, it will fail, so if so drop the foreign key constraints. KEEP TRACK OF WHICH TABLES YOU RUN THIS FOR SO YOU CAN ADD THE CONSTRAINTS BACK IN LATER!!!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
Once all of your foreign key constraints have been removed, you'll be able to remove the PK constraint, drop that column, rename your temp column, and add the PK constraint to that column:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
alter table yourTable drop column id;
EXEC sp_rename 'yourTable.tempId', 'id', 'COLUMN';
ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id)
commit;
Finally, add the FK constraints back in:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
El Fin!
I just had this same problem. 4 statements in SSMS instead of using the GUI and it was very fast.
Make a new column
alter table users add newusernum int;
Copy values over
update users set newusernum=usernum;
Drop the old column
alter table users drop column usernum;
Rename the new column to the old column name
EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';
Following script removes Identity field for a column named 'Id'
Hope it helps.
BEGIN TRAN
BEGIN TRY
EXEC sp_rename '[SomeTable].[Id]', 'OldId';
ALTER TABLE [SomeTable] ADD Id int NULL
EXEC ('UPDATE [SomeTable] SET Id = OldId')
ALTER TABLE [SomeTable] NOCHECK CONSTRAINT ALL
ALTER TABLE [SomeTable] DROP CONSTRAINT [PK_constraintName];
ALTER TABLE [SomeTable] DROP COLUMN OldId
ALTER TABLE [SomeTable] ALTER COLUMN [Id] INTEGER NOT NULL
ALTER TABLE [SomeTable] ADD CONSTRAINT PK_JobInfo PRIMARY KEY (Id)
ALTER TABLE [SomeTable] CHECK CONSTRAINT ALL
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE ()
END CATCH
Bellow code working as fine, when we don't know identity column name.
Need to copy data into new temp table like Invoice_DELETED.
and next time we using:
insert into Invoice_DELETED select * from Invoice where ...
SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = #InvoiceID
For more explanation see:
https://dba.stackexchange.com/a/138345/101038
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
However above code works only if no primary-foreign key relation
In SQL Server you can turn on and off identity insert like this:
SET IDENTITY_INSERT table_name ON
-- run your queries here
SET IDENTITY_INSERT table_name OFF
Just for someone who have the same problem I did.
If you just want to make some insert just once you can do something like this.
Lets suppose you have a table with two columns
ID Identity (1,1) | Name Varchar
and want to insert a row with the ID = 4. So you Reseed it to 3 so the next one is 4
DBCC CHECKIDENT([YourTable], RESEED, 3)
Make the Insert
INSERT INTO [YourTable]
( Name )
VALUES ( 'Client' )
And get your seed back to the highest ID, lets suppose is 15
DBCC CHECKIDENT([YourTable], RESEED, 15)
Done!
I had the same requirement, and you could try this way, which I personally recommend you, please manually design your table and generate the script, and what I did below was renaming the old table and also its constraint for backup.
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIdtDateTimeStamp
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIbHotelPreLoaded
GO
CREATE TABLE dbo.Tmp_SI_Provider_Profile
(
SI_lProvider_Profile_ID int NOT NULL,
SI_lSerko_Integrator_Token_ID int NOT NULL,
SI_sSerko_Integrator_Provider varchar(50) NOT NULL,
SI_sSerko_Integrator_Profile varchar(50) NOT NULL,
SI_dtDate_Time_Stamp datetime NOT NULL,
SI_lProvider_ID int NULL,
SI_sDisplay_Name varchar(10) NULL,
SI_lPurchased_From int NULL,
SI_sProvider_UniqueID varchar(255) NULL,
SI_bHotel_Pre_Loaded bit NOT NULL,
SI_sSiteName varchar(255) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIdtDateTimeStamp DEFAULT (getdate()) FOR SI_dtDate_Time_Stamp
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIbHotelPreLoaded DEFAULT ((0)) FOR SI_bHotel_Pre_Loaded
GO
IF EXISTS(SELECT * FROM dbo.SI_Provider_Profile)
EXEC('INSERT INTO dbo.Tmp_SI_Provider_Profile (SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName)
SELECT SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName FROM dbo.SI_Provider_Profile WITH (HOLDLOCK TABLOCKX)')
GO
-- Rename the primary key constraint or unique key In SQL Server constraints such as primary keys or foreign keys are objects in their own right, even though they are dependent upon the "containing" table.
EXEC sp_rename 'dbo.SI_Provider_Profile.PK_SI_Provider_Profile', 'PK_SI_Provider_Profile_Old';
GO
-- backup old table in case of
EXECUTE sp_rename N'dbo.SI_Provider_Profile', N'SI_Provider_Profile_Old', 'OBJECT'
GO
EXECUTE sp_rename N'dbo.Tmp_SI_Provider_Profile', N'SI_Provider_Profile', 'OBJECT'
GO
ALTER TABLE dbo.SI_Provider_Profile ADD CONSTRAINT
PK_SI_Provider_Profile PRIMARY KEY NONCLUSTERED
(
SI_lProvider_Profile_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT TRANSACTION
ALTER TABLE TABLE_NAME MODIFY (COLUMN_NAME DROP IDENTITY);

SQL Server 2008 Script to Drop PK Constraint that has a System Generated Name

I am trying to add a clustered index to an existing table in SQL Server 2008, and it needs to be an automated script, because this table exists on several databases across several servers.
In order to add a clustered index I need to remove the PK constraint on the table, and then re-add it as unclustered. The problem is the name of the PK constraint is auto-generated, and there is a guid appended to the end, so it's like "PK_[Table]_D9F9203400."
The name is different across all databases, and I'm not sure how to write an automated script that drops a PK constraint on a table in which I don't know the name of the constraint. Any help is appreciated!
UPDATE:
Answer below is what I used. Full script:
Declare #Val varchar(100)
Declare #Cmd varchar(1000)
Set #Val = (
select name
from sysobjects
where xtype = 'PK'
and parent_obj = (object_id('[Schema].[Table]'))
)
Set #Cmd = 'ALTER TABLE [Table] DROP CONSTRAINT ' + #Val
Exec (#Cmd)
GO
ALTER TABLE [Table] ADD CONSTRAINT PK_Table
PRIMARY KEY NONCLUSTERED (TableId)
GO
CREATE UNIQUE CLUSTERED INDEX IX_Table_Column
ON Table (Column)
GO
You can look up the name of the constraint and write a bit of dynamic SQL to handle the drop.
SELECT name
FROM sys.key_constraints
WHERE parent_object_id = object_id('YourSchemaName.YourTableName')
AND type = 'PK';

Remove Identity from a column in a table

We have a 5GB table (nearly 500 million rows) and we want to remove the identity property on one of the column, but when we try to do this through SSMS - it times out.
Can this be done through T-SQL?
You cannot remove an IDENTITY specification once set.
To remove the entire column:
ALTER TABLE yourTable
DROP COLUMN yourCOlumn;
Information about ALTER TABLE here
If you need to keep the data, but remove the IDENTITY column, you will need to:
Create a new column
Transfer the data from the existing IDENTITY column to the new column
Drop the existing IDENTITY column.
Rename the new column to the original column name
If you want to do this without adding and populating a new column, without reordering the columns, and with almost no downtime because no data is changing on the table, let's do some magic with partitioning functionality (but since no partitions are used you don't need Enterprise edition):
Remove all foreign keys that point to this table
Script the table to be created; rename everything e.g. 'MyTable2', 'MyIndex2', etc.
Remove the IDENTITY specification.
You should now have two "identical"-ish tables, one full, the other empty with no IDENTITY.
Run ALTER TABLE [Original] SWITCH TO [Original2]
Now your original table will be empty and the new one will have the data. You have switched the metadata for the two tables (instant).
Drop the original (now-empty table), exec sys.sp_rename to rename the various schema objects back to the original names, and then you can recreate your foreign keys.
For example, given:
CREATE TABLE Original
(
Id INT IDENTITY PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value ON Original (Value);
INSERT INTO Original
SELECT 'abcd'
UNION ALL
SELECT 'defg';
You can do the following:
--create new table with no IDENTITY
CREATE TABLE Original2
(
Id INT PRIMARY KEY
, Value NVARCHAR(300)
);
CREATE NONCLUSTERED INDEX IX_Original_Value2 ON Original2 (Value);
--data before switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
ALTER TABLE Original SWITCH TO Original2;
--data after switch
SELECT 'Original', *
FROM Original
UNION ALL
SELECT 'Original2', *
FROM Original2;
--clean up
IF NOT EXISTS (SELECT * FROM Original) DROP TABLE Original;
EXEC sys.sp_rename 'Original2.IX_Original_Value2', 'IX_Original_Value', 'INDEX';
EXEC sys.sp_rename 'Original2', 'Original', 'OBJECT';
UPDATE Original
SET Id = Id + 1;
SELECT *
FROM Original;
For the record, as this has become increasingly popular, I have wanted to track down the original source (I didn't think of it myself), but of course I've long forgotten where I found the original idea. It may have been here; this was the only one I could find predating this answer (time flies, boys and girls): https://social.technet.microsoft.com/wiki/contents/articles/17738.sql-server-quick-way-to-remove-the-identity-property.aspx
This gets messy with foreign and primary key constraints, so here's some scripts to help you on your way:
First, create a duplicate column with a temporary name:
alter table yourTable add tempId int NOT NULL default -1;
update yourTable set tempId = id;
Next, get the name of your primary key constraint:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'yourTable';
Now try drop the primary key constraint for your column:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
If you have foreign keys, it will fail, so if so drop the foreign key constraints. KEEP TRACK OF WHICH TABLES YOU RUN THIS FOR SO YOU CAN ADD THE CONSTRAINTS BACK IN LATER!!!
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'otherTable';
alter table otherTable drop constraint fk_otherTable_yourTable;
commit;
..
Once all of your foreign key constraints have been removed, you'll be able to remove the PK constraint, drop that column, rename your temp column, and add the PK constraint to that column:
ALTER TABLE yourTable DROP CONSTRAINT PK_yourTable_id;
alter table yourTable drop column id;
EXEC sp_rename 'yourTable.tempId', 'id', 'COLUMN';
ALTER TABLE yourTable ADD CONSTRAINT PK_yourTable_id PRIMARY KEY (id)
commit;
Finally, add the FK constraints back in:
alter table otherTable add constraint fk_otherTable_yourTable foreign key (yourTable_id) references yourTable(id);
..
El Fin!
I just had this same problem. 4 statements in SSMS instead of using the GUI and it was very fast.
Make a new column
alter table users add newusernum int;
Copy values over
update users set newusernum=usernum;
Drop the old column
alter table users drop column usernum;
Rename the new column to the old column name
EXEC sp_RENAME 'users.newusernum' , 'usernum', 'COLUMN';
Following script removes Identity field for a column named 'Id'
Hope it helps.
BEGIN TRAN
BEGIN TRY
EXEC sp_rename '[SomeTable].[Id]', 'OldId';
ALTER TABLE [SomeTable] ADD Id int NULL
EXEC ('UPDATE [SomeTable] SET Id = OldId')
ALTER TABLE [SomeTable] NOCHECK CONSTRAINT ALL
ALTER TABLE [SomeTable] DROP CONSTRAINT [PK_constraintName];
ALTER TABLE [SomeTable] DROP COLUMN OldId
ALTER TABLE [SomeTable] ALTER COLUMN [Id] INTEGER NOT NULL
ALTER TABLE [SomeTable] ADD CONSTRAINT PK_JobInfo PRIMARY KEY (Id)
ALTER TABLE [SomeTable] CHECK CONSTRAINT ALL
COMMIT TRAN
END TRY
BEGIN CATCH
ROLLBACK TRAN
SELECT ERROR_MESSAGE ()
END CATCH
Bellow code working as fine, when we don't know identity column name.
Need to copy data into new temp table like Invoice_DELETED.
and next time we using:
insert into Invoice_DELETED select * from Invoice where ...
SELECT t1.*
INTO Invoice_DELETED
FROM Invoice t1
LEFT JOIN Invoice ON 1 = 0
--WHERE t1.InvoiceID = #InvoiceID
For more explanation see:
https://dba.stackexchange.com/a/138345/101038
ALTER TABLE tablename add newcolumn int
update tablename set newcolumn=existingcolumnname
ALTER TABLE tablename DROP COLUMN existingcolumnname;
EXEC sp_RENAME 'tablename.oldcolumn' , 'newcolumnname', 'COLUMN'
However above code works only if no primary-foreign key relation
In SQL Server you can turn on and off identity insert like this:
SET IDENTITY_INSERT table_name ON
-- run your queries here
SET IDENTITY_INSERT table_name OFF
Just for someone who have the same problem I did.
If you just want to make some insert just once you can do something like this.
Lets suppose you have a table with two columns
ID Identity (1,1) | Name Varchar
and want to insert a row with the ID = 4. So you Reseed it to 3 so the next one is 4
DBCC CHECKIDENT([YourTable], RESEED, 3)
Make the Insert
INSERT INTO [YourTable]
( Name )
VALUES ( 'Client' )
And get your seed back to the highest ID, lets suppose is 15
DBCC CHECKIDENT([YourTable], RESEED, 15)
Done!
I had the same requirement, and you could try this way, which I personally recommend you, please manually design your table and generate the script, and what I did below was renaming the old table and also its constraint for backup.
/* To prevent any potential data loss issues, you should review this script in detail before running it outside the context of the database designer.*/
BEGIN TRANSACTION
SET QUOTED_IDENTIFIER ON
SET ARITHABORT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
COMMIT
BEGIN TRANSACTION
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIdtDateTimeStamp
GO
ALTER TABLE dbo.SI_Provider_Profile
DROP CONSTRAINT DF_SI_Provider_Profile_SIbHotelPreLoaded
GO
CREATE TABLE dbo.Tmp_SI_Provider_Profile
(
SI_lProvider_Profile_ID int NOT NULL,
SI_lSerko_Integrator_Token_ID int NOT NULL,
SI_sSerko_Integrator_Provider varchar(50) NOT NULL,
SI_sSerko_Integrator_Profile varchar(50) NOT NULL,
SI_dtDate_Time_Stamp datetime NOT NULL,
SI_lProvider_ID int NULL,
SI_sDisplay_Name varchar(10) NULL,
SI_lPurchased_From int NULL,
SI_sProvider_UniqueID varchar(255) NULL,
SI_bHotel_Pre_Loaded bit NOT NULL,
SI_sSiteName varchar(255) NULL
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIdtDateTimeStamp DEFAULT (getdate()) FOR SI_dtDate_Time_Stamp
GO
ALTER TABLE dbo.Tmp_SI_Provider_Profile ADD CONSTRAINT
DF_SI_Provider_Profile_SIbHotelPreLoaded DEFAULT ((0)) FOR SI_bHotel_Pre_Loaded
GO
IF EXISTS(SELECT * FROM dbo.SI_Provider_Profile)
EXEC('INSERT INTO dbo.Tmp_SI_Provider_Profile (SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName)
SELECT SI_lProvider_Profile_ID, SI_lSerko_Integrator_Token_ID, SI_sSerko_Integrator_Provider, SI_sSerko_Integrator_Profile, SI_dtDate_Time_Stamp, SI_lProvider_ID, SI_sDisplay_Name, SI_lPurchased_From, SI_sProvider_UniqueID, SI_bHotel_Pre_Loaded, SI_sSiteName FROM dbo.SI_Provider_Profile WITH (HOLDLOCK TABLOCKX)')
GO
-- Rename the primary key constraint or unique key In SQL Server constraints such as primary keys or foreign keys are objects in their own right, even though they are dependent upon the "containing" table.
EXEC sp_rename 'dbo.SI_Provider_Profile.PK_SI_Provider_Profile', 'PK_SI_Provider_Profile_Old';
GO
-- backup old table in case of
EXECUTE sp_rename N'dbo.SI_Provider_Profile', N'SI_Provider_Profile_Old', 'OBJECT'
GO
EXECUTE sp_rename N'dbo.Tmp_SI_Provider_Profile', N'SI_Provider_Profile', 'OBJECT'
GO
ALTER TABLE dbo.SI_Provider_Profile ADD CONSTRAINT
PK_SI_Provider_Profile PRIMARY KEY NONCLUSTERED
(
SI_lProvider_Profile_ID
) WITH( PAD_INDEX = OFF, FILLFACTOR = 90, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT TRANSACTION
ALTER TABLE TABLE_NAME MODIFY (COLUMN_NAME DROP IDENTITY);

A stored proc to copy table data including any default value or binding data via a SQL script running within SQL Server

I would like to be able to copy a table and it's data and also still have any default value or binding (as it is labelled within SQL Server Management console) constraints copied over.
The script below is a testing script to demonstrate the idea. The last line I assume needs to be replaced with a call to a custom stored proc?
Note: The source table (aSourceTbl) schema varies and can change over time.
--TEST SETUP
--Delete the prev tables so test script can be replayed
IF OBJECT_ID('aSourceTbl', 'U') IS NOT NULL
DROP TABLE aSourceTbl;
IF OBJECT_ID('aSourceCopyTbl', 'U') IS NOT NULL
DROP TABLE aSourceCopyTbl;
--Simple table to demonstrate table copying does not carry over the table constraits
CREATE TABLE [dbo].[aSourceTbl](
[aValue] [int] NOT NULL,
[DELETED] [int] NOT NULL
) ON [PRIMARY]
--Add some dummy data
INSERT INTO aSourceTbl (aValue, DELETED) VALUES (1,2);
INSERT INTO aSourceTbl (aValue, DELETED) VALUES (3,4);
--Add constraints of default values of 0 in this case
ALTER TABLE [dbo].[aSourceTbl] ADD CONSTRAINT [DF_aSourceTbl_aValue] DEFAULT ((0)) FOR [aValue]
ALTER TABLE [dbo].[aSourceTbl] ADD CONSTRAINT [DF_aSourceTbl_DELETED] DEFAULT ((0)) FOR [DELETED]
--Actual Required SQL script from here down
--The line below works nicely but does not copy the 2 constraints from the lines above into the new table.
--TODO QUESTION: Replace line below with the same functionaility + the constraints are also copied into new table
Select * INTO aSourceCopyTbl FROM aSourceTbl
Could you please help me by suggesting a suitable stored proc that can replace the last line in above SQL snippet? Any help greatly appreciated :)
References:
Similar SO Question however focuses on PK constraints. I am only interested in default value constraints in this case.
You can execute this code after the last row which will replicate the defauld constraints to the new table (replace the variables with your table names).
declare #table_name sysname, #new_table sysname, #cmd varchar(max)
select #table_name = 'SOURCE_TABLE', #cmd = '', #new_table = 'TEST_TABLE'
select #cmd = #cmd+'ALTER TABLE '+#new_table+' ADD CONSTRAINT [DF_' +#new_table+'_'+a.name+'] DEFAULT '+b.definition+' FOR['+a.name+'];
'
from sys.columns a
join sys.default_constraints b on a.object_id = b.parent_object_id and a.column_id = b.parent_column_id
where a.object_id = object_id(#table_name)
print #cmd
exec (#cmd)