sp_MSforeachtable to execute procedure on each table - sql

I want to print some dynamic query to execute a procedure on all tables in the database. This is what I've written so far -
EXEC SP_MSFOREACHTABLE '
IF EXISTS(SELECT * FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME="EMAIL_S" AND TABLE_NAME=PARSENAME("?",1))
BEGIN
PRINT ''EXEC DROPCONSTANT #TBLNAME=''+PARSENAME("?",1)
+'', #FLDNAME=''''EMAIL_S'''' ''
PRINT CHAR(10)+CHAR(13)
END
'
The output is not what I expect it to be -
EXEC DROPCONSTANT #TBLNAME=bill, #FLDNAME='EMAIL_S'
But what I really want it -
EXEC DROPCONSTANT #TBLNAME='bill', #FLDNAME='EMAIL_S'

How about this instead:
DECLARE #output NVARCHAR(MAX) = N'';
SELECT #output += CHAR(13) + CHAR(10)
+ 'EXEC DROPCONSTANT #TBLNAME=''' + t.name + ''','
+ '#FLDNAME=''EMAIL_S'';'
FROM sys.tables AS t
INNER JOIN sys.columns AS c
ON t.[object_id] = c.[object_id]
WHERE c.name = 'EMAIL_S';
SELECT #output;
-- EXEC sp_executesql #output;

You need to add a bunch of '.
PRINT ''DROPCONSTANT #TBLNAME=''''''+PARSENAME("?",1)+'''''', #FLDNAME=''''EMAIL_S'''' ''

Related

View columns from tables where name like 'ENG_Parameters_%'

I am trying to create a SQL View that will load columns:
[item],[manufacturer_item],[symbol],[footprint]
from any table that matches the name ENG_Parameter_%.
I need to leave it generic because, at any point in time, ENG_Parameter_% might have new or removed tables, so I cannot just hard-code any table names.
Is there a SQL command that could be made to generate this?
The dynamic sql to create the views:
DECLARE #SQL nvarchar(2000);
SET #SQL=N' SELECT
''CREATE VIEW [vw'' + t.name + '']
AS
SELECT [item],[manufacturer_item],[symbol],[footprint]
FROM ['' + t.name + '']'' AS sql_for_view
FROM sys.columns c
INNER JOIN sys.tables t
ON c.object_id=t.object_id
WHERE c.name LIKE ''ENG_Parameter_%''';
exec sp_executesql #SQL;
Thanks to #OwlsSleeping answer (StackOverflow SQL-UNION ALL), this ended up with exactly what I needed:
DECLARE #SQL nvarchar(max)
select #SQL = COALESCE(#SQL , '') + 'SELECT [item],[manufacturer_item],[symbol],
[footprint] FROM [' + TABLE_NAME + '] UNION ALL '
FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME LIKE 'ENG_Parameters_%'
SELECT #SQL = LEFT(#SQL, LEN(#SQL) - 11)
exec sp_executesql #SQL;

Tsql. Dynamic SQL in cursor

‌‌‌Please I REALLY NEED YOUR HELP !!
I‌ want to create a dynamic sql in a cursor.
I‌ want to replace the database DB1 by the variable #Database
I have lot error. I don't know why !!!
‌‌`
‌declare #SQL NVARCHAR (max)
DECLARE #database NVARCHAR (50) = 'TEST'
--DECLARE c CURSOR FOR
IF OBJECT_ID('tempdb..#SQL') IS NOT NULL
DROP TABLE #SQL
SELECT SQL = 'IF OBJECT_ID('''
+ QUOTENAME(SCHEMA_NAME(o.[schema_id]))
+ '.' + QUOTENAME(o.name) + ''') IS NOT NULL
BEGIN
DROP VIEW '
+ QUOTENAME(SCHEMA_NAME(o.[schema_id]))
+ '.' + QUOTENAME(o.name) + ';
END'
+ CHAR(13) + CHAR(10) + 'GO'
+ CHAR(13) + CHAR(10) + Definition
into #SQL
FROM [DB1].sys.sql_modules AS s
INNER JOIN [DB1].sys.objects AS o
ON s.[object_id] = o.[object_id]
WHERE o.type_desc = 'VIEW';
DECLARE c CURSOR FOR
SELECT SQL FROM #SQL
OPEN c
FETCH NEXT FROM c INTO #sql
WHILE ##FETCH_STATUS = 0
BEGIN
-- SET #sql = REPLACE(#sql,'''','''''')
SET #sql = ' EXEC (''' + REPLACE(REPLACE(#SQL, '''', ''''''), 'GO', '''); EXEC(''') + ''');'
--'USE [' + #Name + ']; EXEC(''' + #sql + ''')'
exec (#sql)
FETCH NEXT FROM c INTO #sql
END
CLOSE c
DEALLOCATE c
`
Try to remove the square bracket in 2 lines. Hope to help, my friend.
FROM DB1.sys.sql_modules AS s
INNER JOIN DB1.sys.objects AS o
Good day,
Please check if below code solve your needs:
Note! (1) THIS CODE WAS NOT TESTED! (2) Read the comments inside the code!
-- Step 1: INSERT into New Table
IF OBJECT_ID('tempdb..#SQL') IS NOT NULL
DROP TABLE #SQL
SELECT MySQL = '
IF OBJECT_ID(''' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + '.' + QUOTENAME(o.name) + ''') IS NOT NULL BEGIN
DROP VIEW ' + QUOTENAME(SCHEMA_NAME(o.[schema_id])) + '.' + QUOTENAME(o.name) + ';
END
GO
' + [definition]
into #SQL
FROM sys.sql_modules AS s
INNER JOIN sys.objects AS o ON s.[object_id] = o.[object_id]
WHERE o.type_desc = 'VIEW';
-- always test each step! If this step seems OK, then we will mark the select as comment
select * from #SQL
-- Step 2: loop through all rows that we inserted to the new table, using CURSOR
DECLARE c CURSOR FOR
SELECT MySQL FROM #SQL
OPEN c
declare #SQL NVARCHAR (max)
FETCH NEXT FROM c INTO #sql
WHILE ##FETCH_STATUS = 0 BEGIN
SET #sql =
+ '------START-----' -- This will help us during the check while we pring the text
+ CHAR(13) + CHAR(10)
+ 'EXEC (''' + REPLACE(REPLACE(#SQL, '''', ''''''), 'GO', '''); EXEC(''') + ''');'
-- Again, always check result BEFORE executing it!
PRINT #sql
-- If above results are all well and only if you tested them manually, the we can make the PRINT a comment and exeute the query
--exec (#sql)
FETCH NEXT FROM c INTO #sql
END
CLOSE c
DEALLOCATE c

Drop Several Tables at Once

I have some tables that I need to drop on a regular basis. The names of the tables sometimes change but the table names always begin with 'db_comp_temp'. Is it possible to write some SQL that will in effect do something like:
DROP TABLE db_comp_temp*
Thanks in advance,
No, there is no wildcard support in DDL.
DECLARE #sql nvarchar(max) = N'';
SELECT #sql += N'DROP TABLE ' + QUOTENAME(s.name)
+ '.' + QUOTENAME(t.name) + ';
' FROM sys.tables AS t
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE t.name LIKE N'db[_]comp[_]temp%';
PRINT #sql;
-- EXEC sys.sp_executesql #sql;
Or:
DECLARE #sql nvarchar(max) = N'';
SELECT #sql += N'
,' + QUOTENAME(s.name) + '.' + QUOTENAME(t.name)
FROM sys.tables AS t
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE t.name LIKE N'db[_]comp[_]temp%';
SET #sql = N'DROP TABLE ' + STUFF(#sql, 1, 1, '');
PRINT #sql;
-- EXEC sys.sp_executesql #sql;
You could also do it with FOR XML PATH but I don't think it's necessary when you're not grouping the result into another outer query.

Dynamic update statement with variable column names

We're looking to do an update in several SQL Server databases to change all NULL values in a certain table to be empty strings instead of NULL. We're potentially going to be doing this across hundreds of databases. The table name will always be the same, but the column names are variable based on how the front-end application is configured (don't judge... I didn't create this system).
Is there a way to do an update on all of these columns without knowing the column names ahead of time?
You can pass the name of the column in dynamic sql:
declare #sql nvarchar (1000);
set #sql = N'update table set ' + #column_name + '= ''''';
exec sp_executesql #sql;
You can look in the sys.columns table and join on the table name or object_id.
DECLARE #OBJ_ID INT
SELECT #OBJ_ID = OBJECT_ID
FROM SYS.tables
WHERE name = 'YOURTABLE'
SELECT * FROM SYS.columns
WHERE OBJECT_ID = #OBJ_ID
You could use the name field from the sys.columns query as a basis to perform the update on.
Assuming you want all columns of varchar/char types only (or change the type filter to whatever you need):
DECLARE #tableName varchar(10)
SET #tableName = 'yourtablenamehere'
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + #tableName + ' SET ' + c.name + ' = '''' WHERE ' + c.name + ' IS NULL ;'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE t.name = #tableName AND y.name IN ('varchar', 'nvarchar', 'char', 'nchar')
EXEC (#sql)
This can be achieved with cursors. You first select the column names like #Darren mentioned, then you Set a Cursor with those values and loop:
Open oColumnsCursor
Fetch Next From oColumnscursor
Into #ColumnName
While ##FETCH_STATUS=0
Begin
Set #oQuery = 'Update [DB]..[Table] Set [' + #ColumnName + '] = ''NewValue'' Where [' + #ColumnName + '] = ''OldValue'''
Execute(#oQuery)
Fetch Next From oColumnscursor Into #ColumnName
Set #oCount = #oCount + 1
End
Close oColumnsCursor;
Deallocate oColumnsCursor;
This will work when you know the Table Name:
DECLARE #tableName varchar(10)
SET #tableName = 'Customers'
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + #tableName + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar')
AND t.name = #tableName;
EXEC(#sql);
And this will iterate all Tables and all Columns in a Db:
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + t.name + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar');
EXEC(#sql);
Below is the procedure.
ALTER PROCEDURE [dbo].[util_db_updateRow]
#colval_name NVARCHAR (30), -- column and values e.g. tax='5.50'
#idf_name NVARCHAR (300), -- column name
#idn_name NVARCHAR (300), -- column value
#tbl_name NVARCHAR (100) -- table name
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX)
-- construct SQL
SET #sql = 'UPDATE ' + #tbl_name + ' SET ' + #colval_name +
' WHERE ' + #idf_name + '=' + #idn_name;
-- execute the SQL
EXEC sp_executesql #sql
SET NOCOUNT OFF
RETURN
END
Below is the stored procedure where you can pass Schema Name, Table Name and list of column names separted by comma.It works only in Sql Server 2016 or higher.
CREATE OR ALTER PROCEDURE UpdateData
(#SchemaName NVARCHAR(Max),#TableName NVARCHAR(MAX),#ColumnNames NVARCHAR(MAX))
AS
BEGIN
DECLARE #DynamicSql NVARCHAR(MAX);
SET #DynamicSql = 'UPDATE ' +'[' +#SchemaName+'].' + '[' +#TableName+']' +' SET ' + STUFF((SELECT ', [' + C.name + '] = ' + '''NEW_VALUE'''
FROM sys.columns C
INNER JOIN sys.tables T ON T.object_id = C.object_id
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
WHERE
T.name = #TableName
AND S.Name = #SchemaName
AND [C].[name] in (SELECT VALUE FROM string_split(#ColumnNames,','))
FOR XML PATH('')), 1,1, '')
print #DynamicSql;
EXEC (#DynamicSql);
END

SQL Server 2008 delete all tables under special schema

Hello I would like to know is is possible to drop all tables in database what was created under custom schema for example DBO1...with one sql query or special script.
Thanks
This will generate all the DROP TABLE statements for you and PRINT the SQL statement out.
You can then validate it's what you expect before copying and executing. Just make sure you are 100% sure...maybe take a backup first :)
DECLARE #SqlStatement NVARCHAR(MAX)
SELECT #SqlStatement =
COALESCE(#SqlStatement, N'') + N'DROP TABLE [DBO1].' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'DBO1' and TABLE_TYPE = 'BASE TABLE'
PRINT #SqlStatement
Somewhat old thread I know, but I was looking for something like this and found the original answer very helpful. That said, the script will also try to drop views that might exist in that schema and give you an error message because you end up trying to drop a view by issuing a DROP TABLE statement.
I ended up writing this because I needed to drop all tables, views, procedures and functions from a given schema. Maybe not the most elegant way to accomplish this, but it worked for me and I thought I'd share.
DECLARE #Sql VARCHAR(MAX)
, #Schema varchar(20)
SET #Schema = 'Integration' --put your schema name between these quotes
--tables
SELECT #Sql = COALESCE(#Sql,'') + 'DROP TABLE %SCHEMA%.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #Schema
AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME
--views
SELECT #Sql = COALESCE(#Sql,'') + 'DROP VIEW %SCHEMA%.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #Schema
AND TABLE_TYPE = 'VIEW'
ORDER BY TABLE_NAME
--Procedures
SELECT #Sql = COALESCE(#Sql,'') + 'DROP PROCEDURE %SCHEMA%.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = #Schema
AND ROUTINE_TYPE = 'PROCEDURE'
ORDER BY ROUTINE_NAME
--Functions
SELECT #Sql = COALESCE(#Sql,'') + 'DROP FUNCTION %SCHEMA%.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = #Schema
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY ROUTINE_NAME
SELECT #Sql = COALESCE(REPLACE(#Sql,'%SCHEMA%',#Schema), '')
PRINT #Sql
I know this is an old thread but I think the easiest way to do this is by using the undocumented sp_MSforeachtable stored procedure:
EXEC sp_MSforeachtable
#command1 = 'DROP TABLE ?'
, #whereand = 'AND SCHEMA_NAME(schema_id) = ''your_schema_name'' '
A detailed report on this stored procedure can be found here, but in case the link goes dead here are the highlights:
sp_MSforeachtable is a stored procedure that is mostly used to apply a T-SQL command to every table, iteratively, that exists in the current database.
[...]
realized that the question mark (?) it is used as the replacement of the table and during the execution it will be replaced by the appropriate table name.
#command1, #command2, #command3
sp_MSforeachtable stored procedure requires at least one command to be executed (#command1) but it allows up to 3 commands to be executed. Note that it will start to execute first the #command1 and then #command2 and #command3 by the last and this for each table.
#precommand
Use this parameter to provide a command to be executed before the #command1. It is useful to set variable environments or perform any kind of initialization.
#postcommand
Use this parameter to provide a command to be executed after all the commands being executed successfully. It is useful for control and cleanup processes.
#replacechar
By default, a table is represented by the question mark (?) character. This parameter allows you to change this character.
#whereand
By default, sp_MSforeachtable is applied to all user tables in the database. Use this parameter to filter the tables that you want to work with. On the next section, I will explain how you can filter the tables.
Building on the other answers, here is a stored procedure spDropSchema that drops all objects in a schema and the schema itself.
Note that the procedure tries to drop sequence objects too, so it will only work on SQL Server 2012 and above.
IF EXISTS (SELECT * FROM sysobjects WHERE type = 'P' AND name = 'spDropSchema')
BEGIN
DROP PROCEDURE spDropSchema
END
GO
CREATE PROCEDURE spDropSchema(#Schema nvarchar(200))
AS
DECLARE #Sql NVARCHAR(MAX) = '';
--constraints
SELECT #Sql = #Sql + 'ALTER TABLE '+ QUOTENAME(#Schema) + '.' + QUOTENAME(t.name) + ' DROP CONSTRAINT ' + QUOTENAME(f.name) + ';' + CHAR(13)
FROM sys.tables t
inner join sys.foreign_keys f on f.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
WHERE s.name = #Schema
ORDER BY t.name;
--tables
SELECT #Sql = #Sql + 'DROP TABLE '+ QUOTENAME(#Schema) +'.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #Schema AND TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME
--views
SELECT #Sql = #Sql + 'DROP VIEW '+ QUOTENAME(#Schema) +'.' + QUOTENAME(TABLE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #Schema AND TABLE_TYPE = 'VIEW'
ORDER BY TABLE_NAME
--procedures
SELECT #Sql = #Sql + 'DROP PROCEDURE '+ QUOTENAME(#Schema) +'.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = #Schema AND ROUTINE_TYPE = 'PROCEDURE'
ORDER BY ROUTINE_NAME
--functions
SELECT #Sql = #Sql + 'DROP FUNCTION '+ QUOTENAME(#Schema) +'.' + QUOTENAME(ROUTINE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_SCHEMA = #Schema AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY ROUTINE_NAME
--sequences
SELECT #Sql = #Sql + 'DROP SEQUENCE '+ QUOTENAME(#Schema) +'.' + QUOTENAME(SEQUENCE_NAME) + ';' + CHAR(13)
FROM INFORMATION_SCHEMA.SEQUENCES
WHERE SEQUENCE_SCHEMA = #Schema
ORDER BY SEQUENCE_NAME
--types
SELECT #Sql = #Sql + 'DROP TYPE ' + QUOTENAME(#Schema) + '.' + QUOTENAME(t.name) + ';' + CHAR(13)
FROM sys.types t
INNER JOIN sys.schemas s ON t.schema_id = s.schema_id
WHERE t.is_user_defined = 1 AND
s.name = #Schema
ORDER BY s.name
SELECT #Sql = #Sql + 'DROP SCHEMA '+ QUOTENAME(#Schema) + ';' + CHAR(13)
EXECUTE sp_executesql #Sql
GO
Building on #Kevo's answer, I added the following for dropping all foreign key constraints before deleting the tables. I've only tested on SQL2008 R2
select #Sql = COALESCE(#Sql,'') + 'ALTER TABLE %SCHEMA%.' + t.name + ' drop constraint ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13)
from sys.tables t
join sys.foreign_key_columns d on d.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where s.name = #Schema
ORDER BY t.name;
Also building on #Kevo's answer, I added the following while loop for an issue I was having with TSQL Print statement. A message string can be up to 8,000 characters long. If greater than 8,000 the print statement will truncate any remaining characters.
DECLARE #SqlLength int
, #SqlPosition int = 1
, #printMaxLength int = 8000
SET #SqlLength = LEN(#Sql)
WHILE (#SqlLength) > #printMaxLength
BEGIN
PRINT SUBSTRING(#Sql, #SqlPosition, #printMaxLength)
SET #SqlLength = #SqlLength - #printMaxLength
SET #SqlPosition = #SqlPosition + #printMaxLength
END
IF (#SqlLength) < #printMaxLength AND (#SqlLength) > 0
BEGIN
PRINT SUBSTRING(#Sql, #SqlPosition, #printMaxLength)
END
I combined the answers from #raider33 and #Kevo to one solutions for direct execution.
DECLARE #SqlStatement NVARCHAR(MAX)
DECLARE #schema varchar(30) = 'SCHEMA_NAME';
select #SqlStatement = COALESCE(#SqlStatement,'') + 'ALTER TABLE '+#schema+'.' + t.name + ' drop constraint ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13) + CHAR(10)
from sys.tables t
join sys.foreign_key_columns d on d.parent_object_id = t.object_id
inner join sys.schemas s on t.schema_id = s.schema_id
where s.name = #schema
ORDER BY t.name;
SELECT #SqlStatement +=
COALESCE(#SqlStatement, '') + 'DROP TABLE ' + #schema +'.'+ QUOTENAME(TABLE_NAME) + ';' + CHAR(13) + CHAR(10)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #schema
EXECUTE sp_executesql #SqlStatement
Just in case it helps someone, I added this as a stored procedure to the master database to allow it to conveniently used on any db / schema.
It can be called like this:
EXEC master.dbo.dropTablesInSchema 'my_db', 'dbo
Stored procedure create script:
CREATE PROC [master].[dbo].[dropTablesInSchema]
#db nvarchar(max),
#schema nvarchar(max)
AS
BEGIN
DECLARE #Tables TABLE (name nvarchar(max))
INSERT INTO #Tables
EXEC ('SELECT TABLE_NAME FROM [' + #db + '].INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ''' + #schema + ''' and TABLE_TYPE =''BASE TABLE''')
DECLARE #SqlStatement NVARCHAR(MAX)
SELECT #SqlStatement =
COALESCE(#SqlStatement, N'') + N'DROP TABLE [' + #db + '].[' + #schema + '].' + QUOTENAME(NAME) + N';' + CHAR(13)
FROM #Tables
EXEC(#SqlStatement)
END
Building on chris LB's answer, I added
GROUP BY d.constraint_object_id, t.name
because I saw duplicate constraint deletions in my query. constraint_object_id is the FK Constraint ID, as noted at https://msdn.microsoft.com/en-us/library/ms186306.aspx
DECLARE #SqlStatement NVARCHAR(MAX),
#Schema NVARCHAR(20)
SET #Schema = 'aa'
SELECT #SqlStatement =
COALESCE(#SqlStatement,'') + 'ALTER TABLE '+#Schema+'.' + t.name + ' DROP CONSTRAINT ' +
OBJECT_NAME(d.constraint_object_id) + ';' + CHAR(13) + CHAR(10)
FROM sys.tables t
JOIN sys.foreign_key_columns d on t.object_id = d.parent_object_id
INNER JOIN sys.schemas s on t.schema_id = s.schema_id
WHERE s.name = #Schema
GROUP BY d.constraint_object_id, t.name
ORDER BY t.name;
select 'DROP TABLE [TABSCHEMA].' + QUOTENAME(TABLE_NAME) + N';' from INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'TABSCHEMA' and TABLE_TYPE = 'BASE TABLE'
This will generate all the DROP TABLE and DROP VIEW with check exists.
DECLARE #SqlStatement NVARCHAR(MAX)
SELECT #SqlStatement =
COALESCE(#SqlStatement, N'') + N'IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'''+'['+TABLE_SCHEMA+'].' + QUOTENAME(TABLE_NAME) +''' )' + CHAR(13)+
' DROP '+ TABLE_TYPE +' ['+TABLE_SCHEMA+'].' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA in ('SCHEMA1','SCHEMA2','SCHEMA13' )
ORDER BY TABLE_SCHEMA
PRINT REPLACE(#SqlStatement,'DROP BASE TABLE ','DROP TABLE ')
GO
Drop all tables in schema , can be modified to return any subset of tables.
declare #schema varchar(10) = 'temp'
declare #max_number_of_tables int = 1000
declare #sql nvarchar(max)
declare #index int = 0
while (
select count(*)
from
sys.objects obj
join sys.schemas s
on (s.schema_id=obj.schema_id)
where
s.name= #schema
and obj.type = 'U'
AND obj.is_ms_shipped = 0x0) > 0 and #index < #max_number_of_tables
begin
set #index = #index+1
select top 1
#sql = N'DROP TABLE [' + #schema + '].[' + obj.name + ']'
from
sys.objects obj
join sys.schemas s
on (s.schema_id=obj.schema_id)
where
s.name = #schema
and obj.type = 'U'
AND obj.is_ms_shipped = 0x0
order by obj.name
print #sql
execute(#sql)
end
Modification of acepted answer that works just copy pasted.
Change db to your database and set #dbSchema to your schema.
USE db -- CHANGE TO YOUR DB
GO
DECLARE #dbSchema NVARCHAR(200);
SET #dbSchema = 'dbo' -- CHANGE TO YOUR SCHEMA
DECLARE #SqlStatement NVARCHAR(MAX)
SELECT #SqlStatement =
COALESCE(#SqlStatement, N'') + N'DROP TABLE ' +'[' + #dbSchema +']' + '.' + QUOTENAME(TABLE_NAME) + N';' + CHAR(13)
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = #dbSchema and TABLE_TYPE = 'BASE TABLE'
EXEC sp_executesql #SqlStatement