How can I rename a schema using SQL Server?
7 Answers
If you have a large number of objects in a schema, you can use something like this to generate all the changes automatically (it only does tables and views, so before you run it, you might need to expand it to SPs, UDFs, etc.)
USE SandBox
DECLARE @OldSchema AS varchar(255)
DECLARE @NewSchema AS varchar(255)
DECLARE @newLine AS varchar(2) = CHAR(13) + CHAR(10)
SET @OldSchema = 'dbo'
SET @NewSchema = 'StackOverflow'
DECLARE @sql AS varchar(MAX)
SET @sql = 'CREATE SCHEMA [' + @NewSchema + ']' + @newLine
SELECT @sql = @sql + 'GO' + @newLine
SELECT @sql = @sql + 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'
+ @newLine
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @OldSchema
SET @sql = @sql + 'DROP SCHEMA [' + @OldSchema + ']'
PRINT @sql -- NOTE PRINT HAS AN 8000 byte limit - 8000 varchar/4000 nvarchar - see comments
IF (0=1) EXEC (@sql)
-
This doesn't work very well if the views contain references to the oldschema in them, unfortunately :( – Matthew Groves Oct 15 '10 at 14:58
-
@mgroves Yes, but objects in a schema do not require other objects in the same schema to be prefixed, so that's probably a design smell in the first place. You could attempt to catch that by using the view or proc code (stored in the metadata) to look for potential misuses of prefixes. You can catch potential parsing problems problems after a mass move by attempting to refresh all the (non-deterministic) SQL modules. – Cade Roux Oct 15 '10 at 15:53
-
This won't work if you have lots of tables and `@sql` will exceed `varchar(max)`. Unfortunately local variables can't be declared as `text` either. – Rian Schmits Apr 20 '11 at 15:24
-
@Rian Schmits How many objects do you have in a schema? The maximum storage size for VARCHAR(MAX) is 2^31-1 bytes (2,147,483,647 bytes or 2GB - 1 bytes). That's a pretty big script limit. – Cade Roux Apr 20 '11 at 15:50
-
@ Cade Roux I have 220 tables in a schema and the generated script is nowhere near 2GB. So your solution should work, but for some reason doesn't in my case. Could it be a SQL Server setting? – Rian Schmits Apr 20 '11 at 16:11
-
1@Rian Schmits PRINT has an 8000 byte limit. You'll need a custom PRINT SP which breaks up the varchar(MAX) into chunks to print it out (http://blog.falafel.com/Blogs/AdamAnderson/07-02-28/T-SQL_Exceeding_the_8000_Byte_Limit_of_the_PRINT_Statement.aspx). But EXEC doesn't have a problem. – Cade Roux Apr 20 '11 at 16:16
-
@Rian Schmits I'll edit my answer to indicate that problem with PRINT - it IS quite annoying. – Cade Roux Apr 20 '11 at 21:43
-
What if the old schema has extended properties? I adapted your solution to the tSQLt framework, which uses extended properties to mark 'test class' schemas. [Check it out](http://stackoverflow.com/questions/20434667/how-do-i-rename-a-tsqlt-test-class). Thanks, Cade! – Iain Samuel McLean Elder Dec 09 '13 at 00:24
-
IF (0=1) EXEC (@sql) it will always be false, so I think need to remove the IF part from last line, otherwise it works like charm !!! one up vote from me – sib10 Jul 24 '17 at 11:06
-
If you Copy-paste the Print, it doesn't work in one batch. Schema creations must be the only statement in a batch. After a CREATE SCHEMA the GO command must be given. Except from that it's works GREAT! – promicro Jan 04 '18 at 14:32
-
for sprocs add: `SELECT @sql = @sql + 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + SPECIFIC_SCHEMA + '].[' + SPECIFIC_NAME + ']' + @newLine FROM INFORMATION_SCHEMA.ROUTINES WHERE SPECIFIC_SCHEMA = @OldSchema` before the DROP line – ono2012 Aug 28 '18 at 16:59
You move individual objects from one schema to another via:
ALTER SCHEMA NewSchema TRANSFER OldSchema.Object;

- 59,778
- 26
- 187
- 249

- 26,208
- 12
- 60
- 59
-
14
-
2@littlegreen: You can assume the schema was already created since the user asked how to rename, not create. – Phil Apr 29 '12 at 22:36
-
8@Phil - not really. If someone else created `OldSchema` and the intuitive thought is to *rename* it rather than create a new one and transfer objects to it, then it is not certain that the user knows to create the new schema first. – Jason Kleban Oct 13 '14 at 13:05
I have combined both codes above and used cursors to not be limited by the size of the string variables, executing the commands individually. I assume you have already created the new schema and will drop the old one after certifying all is ok. It's safer... :)
DECLARE @OldSchema AS varchar(255)
DECLARE @NewSchema AS varchar(255)
SET @OldSchema = 'dbo'
SET @NewSchema = 'StackOverflow'
DECLARE @sql AS varchar(MAX)
DECLARE @Schema AS varchar(MAX)
DECLARE @Obj AS varchar(MAX)
-- First transfer Tables and Views
DECLARE CU_OBJS CURSOR FOR
SELECT TABLE_SCHEMA, TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = @OldSchema
OPEN CU_OBJS
FETCH NEXT FROM CU_OBJS
INTO @Schema, @Obj
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @sql = 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + @OldSchema + '].[' + @Obj + ']'
PRINT @sql
-- EXEC (@sql)
FETCH NEXT FROM CU_OBJS
INTO @Schema, @Obj
END
CLOSE CU_OBJS
DEALLOCATE CU_OBJS
-- Now transfer Stored Procedures
DECLARE CU_OBJS CURSOR FOR
SELECT sys.schemas.name, sys.procedures.name
FROM sys.procedures,sys.schemas
WHERE sys.procedures.schema_id=sys.schemas.schema_id and sys.schemas.name = @OldSchema
OPEN CU_OBJS
FETCH NEXT FROM CU_OBJS
INTO @Schema, @Obj
WHILE @@FETCH_STATUS = 0
BEGIN
SELECT @sql = 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + @Schema + '].[' + @Obj + ']'
PRINT @sql
-- EXEC (@sql)
FETCH NEXT FROM CU_OBJS
INTO @Schema, @Obj
END
CLOSE CU_OBJS
DEALLOCATE CU_OBJS

- 23,901
- 21
- 124
- 145

- 428
- 5
- 10
-
3I think you have the order of arguments reversed on the first `ALTER` line. The `@NewSchema` should be listed first, after `ALTER SCHEMA`, but you're showing `@OldSchema` first. Otherwise, it works pretty well. It doesn't rename schemas deeply (references within sp's or views), but none of these solutions do, either. – Alan McBee Jun 22 '15 at 19:18
-
@AlanMcBee Thanks for pointing out the schema swap! Had me stumped for a moment :) – FreakinOutMan May 13 '16 at 23:14
The stored procedure to rename the schema which has more tables in SQL server 2008
IF OBJECT_ID ( 'dbo.RenameSchema', 'P' ) IS NOT NULL
DROP PROCEDURE dbo.RenameSchema;
GO
CREATE PROCEDURE dbo.RenameSchema
@OLDNAME varchar(500),
@NEWNAME varchar(500)
AS
/*check for oldschema exist or not */
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = @OLDNAME)
BEGIN
RETURN
END
/* Create the schema with new name */
IF NOT EXISTS (SELECT 1 FROM sys.schemas WHERE name = @NEWNAME)
BEGIN
EXECUTE( 'CREATE SCHEMA ' + @NEWNAME );
END
/* get the object under the old schema and transfer those objects to new schema */
DECLARE Schema_Cursor CURSOR FOR
SELECT ' ALTER SCHEMA ' + @NEWNAME + ' TRANSFER '+ SCHEMA_NAME(SCHEMA_ID)+'.'+ name
as ALTSQL from sys.objects WHERE type IN ('U','V','P','Fn') AND
SCHEMA_NAME(SCHEMA_ID) = @OLDNAME;
OPEN Schema_Cursor;
DECLARE @SQL varchar(500)
FETCH NEXT FROM Schema_Cursor INTO @SQL;
WHILE @@FETCH_STATUS = 0
BEGIN
exec (@SQL)
FETCH NEXT FROM Schema_Cursor INTO @SQL;
END;
CLOSE Schema_Cursor;
DEALLOCATE Schema_Cursor;
/* drop the old schema which should be the user schema */
IF @OLDNAME <> 'dbo' and @OLDNAME <> 'guest'
BEGIN
EXECUTE ('DROP SCHEMA ' + @OLDNAME)
END
GO
Execute the procedure to rename the schema: examples:
EXECUTE RenameSchema 'oldname','newname'
EXECUTE RenameSchema 'dbo','guest'

- 453
- 1
- 5
- 12
This is a short version but works well.
declare @sql varchar(8000), @table varchar(1000), @oldschema varchar(1000), @newschema varchar(1000)
set @oldschema = 'old'
set @newschema = 'dbo'
while exists(select * from sys.tables where schema_name(schema_id) = @oldschema)
begin
select @table = name from sys.tables
where object_id in(select min(object_id) from sys.tables where schema_name(schema_id) = @oldschema)
set @sql = 'alter schema [' + @newschema + '] transfer [' + @oldschema + '].[' + @table + ']'
exec(@sql)
end

- 5,148
- 3
- 46
- 72

- 151
- 2
- 8
-
1Thanks for this! In my case I was moving to a new schema, and had to remember to `CREATE SCHEMA [newSchema]` first! – Ian Grainger Jul 21 '16 at 15:13
For Procedures
USE DatabaseName
DECLARE @OldSchema AS varchar(255)
DECLARE @NewSchema AS varchar(255)
SET @OldSchema = 'ComputerLearn'
SET @NewSchema = 'Basic'
DECLARE @sql AS varchar(MAX)
SET @sql = 'CREATE SCHEMA [' + @NewSchema + ']' + CHAR(13) + CHAR(10)
SELECT @sql = @sql + 'ALTER SCHEMA [' + @NewSchema + '] TRANSFER [' + sys.schemas.name + '].[' + sys.procedures.name + ']'
+ CHAR(13) + CHAR(10)
FROM sys.procedures,sys.schemas
WHERE sys.procedures.schema_id=sys.schemas.schema_id and sys.schemas.name = @OldSchema
SET @sql = @sql + 'DROP SCHEMA [' + @OldSchema + ']'
PRINT @sql
IF (0=1) EXEC (@sql)
-
IF (0=1) EXEC (@sql) it will always be false, so I think need to remove the IF part from last line, otherwise it works like charm !!! one up vote from me. – sib10 Jul 24 '17 at 11:04
Easiest solution that worked for me is:
I have just one schema dbo with two tables PopulationByCountrySTG
and CountryRegionSTG
(1) I created a new schema by executing,
create schema stg
(2) I executed the following commands,
ALTER SCHEMA stg TRANSFER dbo.PopulationByCountrySTG;
ALTER SCHEMA stg TRANSFER dbo.CountryRegionSTG;
All done. Let me know if it works for you.. Thanks Guys.

- 2,282
- 8
- 26
- 34

- 33
- 1
- 1
- 7