How can I set all ID fields to primary key? - sql-server

I have 15 tables in SQL Server. Each of them has an ID (int) column. How can I set all those ID fields to PRIMARY KEY and AUTOINCREMENT in a short or single SQL query?

The script needed to do this is actually not simple but very complicated. Fortunately SMSS can generate it for you (based on changes you make to 1 table). You can then make copies of that script, adapt those copies for each table, and then run them.
Steps:
Make sure that you disabled the SSMS option "Prevent saving changes that require table re-creation":
Then, make the needed changes in the Table Designer for 1 of your tables.
DO NOT press the Save button in the toolbar - instead, right click in the Designer window and choose the option Generate Change Script:
Save the SQL file, it will look something like this:
/* 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
CREATE TABLE dbo.Tmp_Table1
(
ID int NOT NULL IDENTITY (1, 1)
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_Table1 SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_Table1 ON
GO
IF EXISTS(SELECT * FROM dbo.Table1)
EXEC('INSERT INTO dbo.Tmp_Table1 (ID)
SELECT ID FROM dbo.Table1 WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_Table1 OFF
GO
DROP TABLE dbo.Table1
GO
EXECUTE sp_rename N'dbo.Tmp_Table1', N'Table1', 'OBJECT'
GO
ALTER TABLE dbo.Table1 ADD CONSTRAINT
PK_Table1 PRIMARY KEY CLUSTERED
(
ID
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
Make 15 copies of the script file, then in each replace Table1 (or whatever was saved for you) with the respective 15 table names that you want to process.
Also edit each script to INSERT...SELECT the proper columns for each table, if your tables contain data already.
Run the 15 copies.

Related

ALTER COLUMN with INTEGER Datatype, NOT NULL, PRIMARY KEY, auto increment

I have a MySQL QUERY and working fine.
QUERY IS:
ALTER TABLE run
CHANGE RN_RUN_ID RN_RUN_ID INT(11) NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
I tried to execute same Query and modified in MSSQL which is throwing error.
MSSQL QUERY IS:
ALTER TABLE run ALTER COLUMN RN_RUN_ID
RN_RUN_ID INT NOT NULL AUTO_INCREMENT,
ADD PRIMARY KEY (RN_RUN_ID);
ERROR IS:
Msg 102, Level 15, State 1, Line 1
Incorrect syntax near 'AUTO_INCREMENT'.
Can you tell me what I did wrong in this query.
You cant do it directly.
See this post: Adding an identity to an existing column
First answer.
In SQL Server there is no such AUTO_INCREMENT option. Please look at the docs. The equivalent is IDENTITY.
You cannot modify a column directly to become IDENTITY. You need to create a new column on the table, or create a new table and rename it. It has some tricky parts (allowing the insert in the identity column, renaming a column, and some other things). Look this SO answer.
There are also differences on the syntax for adding a PK to a table:
ALTER TABLE run
ADD CONSTRAINT PK PRIMARY KEY (rn_run_id)
If you have acces to SQL Server Management Studio you can get the full script easyly:
add a new diagram to the database
add the table to the diagram (rigth click on the window, and use the contextual menu)
save the diagram (you can delete it later)
right click on the table and choose custom view
right click again on the table, and choose "modify custom view". Add the identity, identity initial value, identity increment, key, etc. required elements to the custom view
modify the column properties in the diagram
go to the "Table designer" menu, and choose the last option "Generate change scripts". You'll get an script which does all the changes for you. For example:
An example of doing this process (by modifying the column id of the table test):
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
CREATE TABLE dbo.Tmp_test
(
id int NOT NULL IDENTITY (10, 2)
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_test SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_test ON
GO
IF EXISTS(SELECT * FROM dbo.test)
EXEC('INSERT INTO dbo.Tmp_test (id)
SELECT id FROM dbo.test WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_test OFF
GO
DROP TABLE dbo.test
GO
EXECUTE sp_rename N'dbo.Tmp_test', N'test', 'OBJECT'
GO
COMMIT
NOTE: the name of the menu options can be different, i don't have an English SSMS at hand right now
Relevant docs:
IDENTITY
DBCC CHECKIDENT
SET IDENTITY_INSERT
ALTER TABLE

Change Auto-Increment, Primary Key field from SMALLINT to INT in SQL Server

What is the best way (low impact/low risk) to change a primary key field from SMALLINT to INT? The field is configured to use "Identity Increment" to auto-increment.
I'm starting with the following SQL:
ALTER TABLE category_types ALTER COLUMN id INT NOT NULL;
However, it generates the following error:
ALTER TABLE ALTER COLUMN id failed because one or more objects access this column.
What else is required? Do I need to drop the keys then recreate them? Will this impact the auto-incrementation?
Note: the table doesn't have too many rows, so the performance of the solution is not critical.
I realise this is an old post, but just in case someone stumbles on it: jciberta gave an answer with a slight error. it should read:
-- Change from smallint to int
SET IDENTITY_INSERT category_types ON
ALTER TABLE category_types DROP CONSTRAINT CategoryTypes
ALTER TABLE category_types ALTER COLUMN id INT
ALTER TABLE category_types ADD CONSTRAINT CategoryTypesPK PRIMARY KEY (id)
SET IDENTITY_INSERT category_types OFF
This is output from sql server management studio but should be of some help. It involves creating a temporary table and then copying existing data to the new table. Dropping the original table and renaming the temp table. If the table was empty, it wouldn't do this and could just modify the original table. SET IDENTITY_INSERT [table] ON/OFF allows you to set the identity column when inserting.
/* 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
CREATE TABLE dbo.Tmp_category_types
(
id int NOT NULL IDENTITY (1, 1),
) ON [PRIMARY]
GO
ALTER TABLE dbo.Tmp_category_types SET (LOCK_ESCALATION = TABLE)
GO
SET IDENTITY_INSERT dbo.Tmp_category_types ON
GO
IF EXISTS(SELECT * FROM dbo.category_types)
EXEC('INSERT INTO dbo.Tmp_category_types (id, x)
SELECT CONVERT(int, id), x FROM dbo.category_types WITH (HOLDLOCK TABLOCKX)')
GO
SET IDENTITY_INSERT dbo.Tmp_category_types OFF
GO
DROP TABLE dbo.category_types
GO
EXECUTE sp_rename N'dbo.Tmp_category_types', N'category_types', 'OBJECT'
GO
ALTER TABLE dbo.category_types ADD CONSTRAINT
PK_category_types PRIMARY KEY CLUSTERED
(
id
) WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
GO
COMMIT
Besides setting IDENTITY_INSERT to off, you have to unlink relationships (primary key, foreign keys) before changing data types. Afterwards you have to link them again.
For instance:
-- Change from smallint to int
SET IDENTITY_INSERT category_types OFF
alter table category_types drop CONSTRAINT CategoryTypesPK
alter table category_types alter column id int
alter table category_types add CONSTRAINT CategoryTypesPK PRIMARY KEY (id)
SET IDENTITY_INSERT category_types ON

'Incorrect SET Options' Error When Building Database Project

We are using Visual Studio and a database project to generate our database.
I just made a number of database changes (including adding a new table named Correspondence) imported those changes into the database project, and attempted to deploy (rebuild) the database.
When I do, I get the following error:
Creating [dbo].[Correspondence]...
Msg 1934, Level 16, State 1, Server (Server Name), Line 1
CREATE TABLE failed because the following SET options have incorrect settings
: 'ANSI_WARNINGS, ANSI_PADDING'. Verify that SET options are correct for use
with indexed views and/or indexes on computed columns and/or filtered indexes
and/or query notifications and/or XML data type methods and/or spatial index
operations.
Can anyone explain this error to me, and help me resolve it? Here's the script the database project uses to create this table.
PRINT N'Creating [dbo].[Correspondence]...';
GO
SET ANSI_NULLS, QUOTED_IDENTIFIER ON;
GO
CREATE TABLE [dbo].[Correspondence] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[WorkbookId] INT NOT NULL,
[ProviderId] UNIQUEIDENTIFIER NOT NULL,
[MessageThreadId] INT NOT NULL,
[MessageThreadType] AS ((1)) PERSISTED NOT NULL
);
GO
SET ANSI_NULLS, QUOTED_IDENTIFIER OFF;
GO
PRINT N'Creating PK_Correspondence...';
GO
ALTER TABLE [dbo].[Correspondence]
ADD CONSTRAINT [PK_Correspondence] PRIMARY KEY CLUSTERED ([Id] ASC)
WITH (ALLOW_PAGE_LOCKS = ON, ALLOW_ROW_LOCKS = ON, PAD_INDEX = OFF,
IGNORE_DUP_KEY = OFF, STATISTICS_NORECOMPUTE = OFF);
GO
According to BOL:
Indexed views and indexes on computed columns store results in the
database for later reference. The stored results are valid only if all
connections referring to the indexed view or indexed computed column
can generate the same result set as the connection that created the
index.
In order to create a table with a persisted, computed column, the following connection settings must be enabled:
SET ANSI_NULLS ON
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
SET ARITHABORT ON
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT ON
SET QUOTED_IDENTIFIER ON
These values are set on the database level and can be viewed using:
SELECT
is_ansi_nulls_on,
is_ansi_padding_on,
is_ansi_warnings_on,
is_arithabort_on,
is_concat_null_yields_null_on,
is_numeric_roundabort_on,
is_quoted_identifier_on
FROM sys.databases
However, the SET options can also be set by the client application connecting to SQL Server.
A perfect example is SQL Server Management Studio which has the default values for SET ANSI_NULLS and SET QUOTED_IDENTIFIER both to ON. This is one of the reasons why I could not initially duplicate the error you posted.
Anyway, to duplicate the error, try this (this will override the SSMS default settings):
SET ANSI_NULLS ON
SET ANSI_PADDING OFF
SET ANSI_WARNINGS OFF
SET ARITHABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET NUMERIC_ROUNDABORT OFF
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE T1 (
ID INT NOT NULL,
TypeVal AS ((1)) PERSISTED NOT NULL
)
You can fix the test case above by using:
SET ANSI_PADDING ON
SET ANSI_WARNINGS ON
I would recommend tweaking these two settings in your script before the creation of the table and related indexes.
I found the solution for this problem:
Go to the Server Properties.
Select the Connections tab.
Check if the ansi_padding option is unchecked.
In my case I was trying to create a table from one database to another on MS SQL Server 2012. Right-clicking on a table and selecting Script Table as > DROP And CREATE To > New Query Editor Window, following script was created:
USE [SAMPLECOMPANY]
GO
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [FK_Employees_Departments]
GO
/****** Object: Table [dbo].[Employees] Script Date: 8/24/2016 9:31:15 PM ******/
DROP TABLE [dbo].[Employees]
GO
/****** Object: Table [dbo].[Employees] Script Date: 8/24/2016 9:31:15 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Employees](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[DepartmentId] [int] NOT NULL,
[FullName] [varchar](50) NOT NULL,
[HireDate] [datetime] NULL
CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_Departments] FOREIGN KEY([DepartmentId])
REFERENCES [dbo].[Departments] ([DepartmentID])
GO
ALTER TABLE [dbo].[Employees] CHECK CONSTRAINT [FK_Employees_Departments]
GO
However when executing above script it was returning the error:
SELECT failed because the following SET options have incorrect
settings: 'ANSI_PADDING'. Verify that SET options are correct for use
with indexed views and/or indexes on computed columns and/or filtered
indexes and/or query notifications and/or XML data type methods and/or
spatial index operations.
The Solution I've found: Enabling the settings on the Top of the script like this:
USE [SAMPLECOMPANY]
GO
/****** Object: Table [dbo].[Employees] Script Date: 8/24/2016 9:31:15 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
ALTER TABLE [dbo].[Employees] DROP CONSTRAINT [FK_Employees_Departments]
GO
/****** Object: Table [dbo].[Employees] Script Date: 8/24/2016 9:31:15 PM ******/
DROP TABLE [dbo].[Employees]
GO
CREATE TABLE [dbo].[Employees](
[EmployeeId] [int] IDENTITY(1,1) NOT NULL,
[DepartmentId] [int] NOT NULL,
[FullName] [varchar](50) NOT NULL,
[HireDate] [datetime] NULL
CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED
(
[EmployeeId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[Employees] WITH CHECK ADD CONSTRAINT [FK_Employees_Departments] FOREIGN KEY([DepartmentId])
REFERENCES [dbo].[Departments] ([DepartmentID])
GO
ALTER TABLE [dbo].[Employees] CHECK CONSTRAINT [FK_Employees_Departments]
GO
SET ANSI_PADDING OFF
GO
Hope this help.
For me, just setting the compatibility level to higher level works fine. To see C.Level :
select compatibility_level from sys.databases where name = [your_database]
In my case, I found that a computed column had been added to the "included columns" of an index. Later, when an item in that table was updated, the merge statement failed with that message. The merge was in a trigger, so this was hard to track down! Removing the computed column from the index fixed it.
I had the same issue with the filtered index and my inserts and updates were failing. All I did was to change the stored procedure that had the insert and update statement to:
create procedure abc
()
AS
BEGIN
SET NOCOUNT ON
SET NUMERIC_ROUNDABORT OFF
SET CONCAT_NULL_YIELDS_NULL ON
SET ANSI_WARNINGS ON
SET ANSI_PADDING ON
end

Change all SQL Server Columns From BigInt to Int

I have inherited a database I need to work with. All the numeric fields have been set to bigint (without reason they are all sub 5000).
How can I programmticaly change all the columns of big int to int? Is this possible will it cause issue with any existing constraints etc?
I only want to change tables and only in the specific database I am working on.
I am using SQL Server 2008 R2
I need to do this for hundreds of fields I am looking for something that I can run once and it will do all the updates for all table fields. I want to keep any existing constraints, null status and default values.
So basically a database wide change of bigint to int without changing anything apart from the field type.
Thanks
Well, I had come across this kind of problem. I had to change int to bigint. This is harder, but possible. It is very easy to change datatype using the following statement:
Alter table myTable alter column targetcolumn int not null
However if your columns are involved in constraint relationship then you have to drop your constraints then alter and then recreate your constraints.
Alter table myTable drop constraint [fkconstraintname]
Alter table myTable alter column targetcolumn int not null
Alter table othertable alter column targetcolumn int not null
Alter table myTable add constraint [fkconstraintname] foreign key (targetcolumn) references othertable(targetcolumn)
EDIT
If you have a lot of constraints then changing it is a real pain in the butt. If there are a lot of tables with constraints and no extreme urge at changing don't do it.
EDIT
Then you can do the following. Connect to Sql Server via Management Studio, right click on the necessary database => Tasks => Generate scripts.
Next => Next
At that point press advanced. There will be a popup. Set Type of data to script to schema and data. Choose whatever output is comfortable for you (file, query window)? Press ok and proceed. It will produce you a complete DDL and DML, like this:
USE [master]
GO
/****** Object: Database [Zafarga] Script Date: 02/02/2012 19:31:55 ******/
CREATE DATABASE [Zafarga] ON PRIMARY
GO
ALTER DATABASE [Zafarga] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [Zafarga].[dbo].[sp_fulltext_database] #action = 'enable'
end
GO
ALTER DATABASE [Zafarga] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_NULLS OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_PADDING OFF
GO
ALTER DATABASE [Zafarga] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [Zafarga] SET ARITHABORT OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [Zafarga] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [Zafarga] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [Zafarga] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [Zafarga] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [Zafarga] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [Zafarga] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [Zafarga] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [Zafarga] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [Zafarga] SET ENABLE_BROKER
GO
ALTER DATABASE [Zafarga] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [Zafarga] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [Zafarga] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [Zafarga] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [Zafarga] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [Zafarga] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [Zafarga] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [Zafarga] SET READ_WRITE
GO
ALTER DATABASE [Zafarga] SET RECOVERY FULL
GO
ALTER DATABASE [Zafarga] SET MULTI_USER
GO
ALTER DATABASE [Zafarga] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [Zafarga] SET DB_CHAINING OFF
GO
EXEC sys.sp_db_vardecimal_storage_format N'Zafarga', N'ON'
GO
USE [Zafarga]
GO
/****** Object: Table [dbo].[Category] Script Date: 02/02/2012 19:31:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Category](
[CategoryId] [bigint] IDENTITY(1,1) NOT NULL,
[CategoryName] [nvarchar](max) NULL,
PRIMARY KEY CLUSTERED
(
[CategoryId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Product] Script Date: 02/02/2012 19:31:56 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Product](
[ProductId] [bigint] IDENTITY(1,1) NOT NULL,
[Name] [nvarchar](max) NULL,
[Price] [decimal](18, 2) NOT NULL,
[CategoryId] [bigint] NOT NULL,
PRIMARY KEY CLUSTERED
(
[ProductId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: ForeignKey [Category_Products] Script Date: 02/02/2012 19:31:56 ******/
ALTER TABLE [dbo].[Product] WITH CHECK ADD CONSTRAINT [Category_Products] FOREIGN KEY([CategoryId])
REFERENCES [dbo].[Category] ([CategoryId])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Product] CHECK CONSTRAINT [Category_Products]
GO
Change all your datatypes appropriately, then run.
As you said all your data is below 5000 rows. So there is no need to modify insert statements.
Be ready it will take a long time.
Hope this was useful.
EDIT
This will generate you a new database, so be ready to rename your original or newly created db.
I think #Oybek says this in one of his addenda, I’m giving him +1, but just to be certain I’ll outline how I’d do it. (This assumes you have a lot of constraints across lots of bigint tables; if not, doing them one by one might be simpler.)
Use SSMS to script the entire database. (That’s right-click the database in the Object Explorer pane, Script Database As, CREATE TO, and I’d to it to a new query window and save it as a file.
Search and replace all bigints with ints. (Do this slowly, make sure you change only what needs to be changed.)
Modify the script to create a new database (different name, different files)
Run and create the database.
The hard part: copy the data from the tables of the old database to the new database.
If, as you say, all the bigints will fit into ints, you shouldn’t have any problems; the hard part is figuring out how to actually do it all. There’s got to be some way to do this via the SSMS Import or Export wizard, but I’m not all that familiar with those tools. Barring that, creating a series of INSERT… SELECT… statements performed in order of parent through child tables, with SET IDENTITY INSERTs as necessary, should do the trick.
I'd do it like this:
Rename YourTable to YourTable_OLD
Right click table -> Script table as Create -> to new query window
adjust the script to use int and rename table to the original
Create the new table and call it YourTable to replace the old
insert YourTable select * from YourTable_OLD
Drop YourTable_OLD (when you're sure everything went ok)
I guess that would be quickest. If you do it column by column it needs to convert it column by column. This involves a lot of IO that could become a problem, depending on the size of your table.
Regards GJ
id addition to the answers, dont forget to check it all the values on the columns are on the integer range (between -2,147,483,648 and 2,147,483,647).
To automate #Oleg Dok's answer you could run his solution inside a script that loops through all tables and all columns on your DB
Regarding to Martin Smith - its much simplier, than I thought:
ALTER TABLE YourTable MODIFY COLUMN OldColumn INT [NOT] NULL
thats all
Old version of answer:
If new column should not be nullable:
ALTER TABLE YourTable ADD NewFIeld INT NOT NULL DEFAULT (CAST(OldField AS INT))
GO
ALTER TABLE YourTable DROP COLUMN OldField
GO
exec sp_rename 'YourTable.NewField', 'OldField', 'COLUMN'
OR which is mostly the same, relaxed for nullable column - does not holds locks on system tables while performing the update
ALTER TABLE YourTable ADD NewFIeld INT NULL
GO
UPDATE YourTable SET NewField=OldField
GO
ALTER TABLE YourTable DROP COLUMN OldField
GO
exec sp_rename 'YourTable.NewField', 'OldField', 'COLUMN'

How do I alter a TEXT column on a database table in SQL server?

In a SQL server database, I have a table which contains a TEXT field which is set to allow NULLs. I need to change this to not allow NULLs. I can do this no problem via Enterprise Manager, but when I try to run the following script, alter table dbo.[EventLog] Alter column [Message] text Not null, I get an error:
Cannot alter column 'ErrorMessage' because it is 'text'.
Reading SQL Books Online does indeed reveal you are not allow to do an ALTER COLUMN on TEXT fields. I really need to be able to do this via a script though, and not manually in Enterprise Manager. What are the options for doing this in script then?
You can use Enterprise Manager to create your script. Right click on the table in EM and select Design. Uncheck the Allow Nulls column for the Text field. Instead of hitting the regular save icon (the floppy), click an icon that looks like a golden scroll with a tiny floppy or just do Table Designer > Generate Change Script from the menu. Save the script to a file so you can reuse it. Here is a sample script:
/* 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
CREATE TABLE dbo.Tmp_TestTable
(
tableKey int NOT NULL,
Description varchar(50) NOT NULL,
TextData text NOT NULL
) ON [PRIMARY]
TEXTIMAGE_ON [PRIMARY]
GO
IF EXISTS(SELECT * FROM dbo.TestTable)
EXEC('INSERT INTO dbo.Tmp_TestTable (tableKey, Description, TextData)
SELECT tableKey, Description, TextData FROM dbo.TestTable WITH (HOLDLOCK TABLOCKX)')
GO
DROP TABLE dbo.TestTable
GO
EXECUTE sp_rename N'dbo.Tmp_TestTable', N'TestTable', 'OBJECT'
GO
ALTER TABLE dbo.TestTable ADD CONSTRAINT
PK_TestTable PRIMARY KEY CLUSTERED
(
tableKey
) ON [PRIMARY]
GO
COMMIT
Create a new field. Copy the data across. Drop the old field. Rename the new field.
I think getting rid of the null values is the easist.
(as raz0rf1sh has said)
CREATE TABLE tmp1( col1 INT identity ( 1, 1 ), col2 TEXT )
GO
INSERT
INTO tmp1
SELECT NULL
GO 10
SELECT *
FROM tmp1
UPDATE tmp1
SET col2 = ''
WHERE col2 IS NULL
ALTER TABLE tmp1
ALTER COLUMN col2 TEXT NOT NULL
SELECT *
FROM tmp1
DROP TABLE tmp1
Off the top of my head, I'd say you need to create a new table with the same structure as the existing table but with your text column set to not null and then run a query to move the records from one to the other.
I realize that's sort of a pseudocode answer but I think that's really the only option you've got.
If others with a better grip on the exact TSQL syntax care to supplement this answer, feel free.
I would update all the columns with NULL values and set it to an empty string, for example, ''. Then you should be able to run your ALTER TABLE script with no problems. A lot less work than creating a new column.
Try to generate the change script from within Enterprise Manager to see how it is done there

Resources