sql server query to retreive all constraint informations - sql-server

I have a workflow that create all table of Database1 called DB1 in another database called DB2; to do that I use the following code:
declare #TableName nvarchar(max)
declare #SqlQuery nvarchar(max)
DECLARE tableCursor CURSOR FOR
select name from wt_delivery.sys.tables where name not like '%temp%' and name not like '%acme%'
order by name
OPEN tableCursor
FETCH tableCursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
set #SqlQuery = N'select * into Acme.dbo.[' + #TableName + N'] from wt_delivery.dbo.[' + #TableName + N'] where 1 = 2'
print #SqlQuery
insert into acme..AcmeLog(Task,error) values('création de la table' + #TableName,ERROR_MESSAGE())
EXECUTE sp_executesql #SqlQuery
FETCH tableCursor INTO #TableName
END
CLOSE tableCursor
DEALLOCATE tableCursor
I then run another query in order to fill DB2 tables with content
The problem is the query select * into tableX from tableY don't copy all the constraints of tableY into tableX.
to create the Foreign key I could create a cursor and use the following query:
SELECT
f.name AS foreign_key_name
,OBJECT_NAME(f.parent_object_id) AS table_name
,COL_NAME(fc.parent_object_id, fc.parent_column_id) AS constraint_column_name
,OBJECT_NAME (f.referenced_object_id) AS referenced_object
,COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS referenced_column_name
,is_disabled
,delete_referential_action_desc
,update_referential_action_desc
FROM sys.foreign_keys AS f
INNER JOIN sys.foreign_key_columns AS fc
ON f.object_id = fc.constraint_object_id
WHERE f.parent_object_id = OBJECT_ID('action');
Are there a way to copy all constraints from one database to another (on the same tables)?
thanks in advance

Related

SQL Server Query to show table name and specific column name and current value in all user table

All of our user tables have a primary key and a rowid_time column. We would like to develop a SQL query which lists:
table name
the value of the primary key
the value of the rowid_time column
(only these three columns and NOT ALL columns of the table)
for all rows and tables in the database.
Is that doable? Ideally this is delivered via a database view.
With dynamic SQL and using a SQL cursor, we can solve the requirement as follows
DECLARE #TableName sysname
DECLARE #SQL nvarchar(max)
DECLARE #PKColumnList nvarchar(max)
DECLARE mycursor CURSOR FAST_FORWARD
FOR
SELECT name FROM sys.tables order by Name
OPEN mycursor
FETCH NEXT FROM mycursor INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
----------------
SELECT #PKColumnList = string_agg(COLUMN_NAME, ',')
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE a
WHERE
EXISTS(
SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS b
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND a.CONSTRAINT_NAME = b.CONSTRAINT_NAME) AND
TABLE_NAME = #tablename
SET #PKColumnList = concat(#PKColumnList+',','rowid_time')
SELECT #SQL = '
;with t1 as (
select ''' + #TableName + ''' as TableName
), t2 as (
SELECT
''' + #TableName + ''' as TableName,
COUNT(*) OVER (Partition By 1) as RowsCount, '
+ #PKColumnList +
' FROM [' + #TableName + ']
)
select
t1.TableName,
t2.RowsCount, '
+ #PKColumnList + '
from t1
full join t2
on t1.TableName = t2.TableName'
EXEC SP_EXECUTESQL #SQL
-----------------
FETCH NEXT FROM mycursor INTO #TableName
END
CLOSE mycursor
DEALLOCATE mycursor
If the PK column for all tables is ID column (no composite key and all PK fields are named as ID for all tables), then SQL sp_MSForEachTable procedure can be used as follows
EXEC sp_MSForEachTable 'SELECT ''?'' as TableName, ID, rowid_time FROM ?'

Execute the query against all databases

I want to execute the below query against all databases.
DECLARE #DB_NAME VARCHAR(30)
SET #DB_NAME = 'Employee';
WITH D
AS
(
SELECT #DB_NAME AS DB_NAME, T.NAME AS TABLE_NAME, C.NAME AS COLUMN_NAME
FROM SYS.tables T
INNER JOIN SYS.columns C
ON T.object_id = C.object_id
WHERE C.name LIKE '%AFFINITY%'
or c.name = 'affinity'
)
SELECT DB_NAME, TABLE_NAME, MAX(COLUMN_NAME) AS COLUMN_NAME FROM D
GROUP BY DB_NAME, TABLE_NAME
ORDER BY TABLE_NAME`
There is the undocumented
EXEC sp_MSforeachdb #command
(A ? in the command will be replaced by the DB name.)
Otherwise you'll need sp_executesql and a cursor over sys.databases.
The latter is supported, sp_MSforeachdb isn't, so for any kind of production system the cursor is the better option (even if a little more work initially). And of course your own query on sys.databases can filter the database list.
USE CAREFULLY:
I assume you have a MYTABLE in each required database, otherwise this wont work.
DECLARE #MYDATABASES NVARCHAR(50)
CREATE TABLE #MYBASE(DB NVARCHAR(50))
DECLARE dbcur CURSOR FOR
SELECT name
FROM sys.databases s
WHERE name not in ('master', 'tempdb', 'msdb') --use this to select all databases but system
--WHERE NAME IN ('myfirstDB', 'mysecondDB', 'mythirdDB') --use this to select only certain databases
OPEN dbcur
FETCH dbcur INTO #MYDATABASES
WHILE ##FETCH_STATUS = 0
BEGIN
/* MY STATEMENT */
DECLARE #SQLSTATEMENT NVARCHAR(MAX)
SELECT #SQLSTATEMENT = N'
SELECT #DB --EDIT WITH YOUR COLUMNS
FROM '+#MYDATABASES+'.dbo.MYTABLE --EDIT THIS
'
INSERT INTO #MYBASE
EXEC sp_executesql #SQLSTATEMENT, N'#DB NVARCHAR(50)', #DB = #MYDATABASES
/* END STATEMENT */
FETCH NEXT FROM dbcur INTO #MYDATABASES
END
CLOSE dbcur
DEALLOCATE dbcur
SELECT DISTINCT * FROM #MYBASE
ORDER BY DB
DROP TABLE #MYBASE

How can I list all databases and all tables of my databases with a final "Attach" and list total row of each table in SQL Server?

I did this. But unfortunately that return all in many table. I want to return all in one unique table. Maybe using "UNION" but I don't know the way to do.
This is my code:
EXEC sp_msforeachdb 'select ''?''AS "DataBase", s.name, t.name AS "Tables",max(si.rows) as "Rows Line"
from [?].sys.tables t inner join [?].sys.schemas s
on t.schema_id = s.schema_id
inner join [?].sys.partitions si on t.object_id = si.object_id
where t.name like "%ATTACH" group by s.name,t.name'`
You cannot do it in a single query.
You could query the sys.databases table to get a temporary table of all your databases, and then run a dynamic query on each database to store the results of the query in your question all in another temporary table.
Then at the end, you just select all rows from the last temporary table.
I have found finally a solution.i just used a Stored Procedures for having the result i was looking for.So decided to post the answer here maybe that will help someone else.
DECLARE #banco_nome nvarchar(MAX), #tabela_nome nvarchar(MAX)
DECLARE #banco_cursor CURSOR
DECLARE #sqlstatement nvarchar(MAX)
DECLARE #count_sql nvarchar(MAX)
DECLARE #total int
DECLARE #RegistrosFotograficos TABLE
(
DatabaseName nvarchar(max),
TableName nvarchar(max),
Total int
)
SET #banco_cursor = CURSOR FORWARD_ONLY FOR
SELECT name FROM sys.databases
OPEN #banco_cursor
FETCH NEXT FROM #banco_cursor INTO #banco_nome
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sqlstatement = 'DECLARE tabela_cursor CURSOR FORWARD_ONLY FOR SELECT TABLE_NAME FROM ' + #banco_nome + '.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = ''BASE TABLE'' AND TABLE_NAME LIKE ''%ATTACH'' ORDER BY TABLE_NAME'
EXEC sp_executesql #sqlstatement
OPEN tabela_cursor
FETCH NEXT FROM tabela_cursor INTO #tabela_nome
WHILE ##FETCH_STATUS = 0
BEGIN
SET #count_sql = 'USE ' + #banco_nome + '; SELECT #total=COUNT(1) FROM ' + #tabela_nome;
EXECUTE sp_executesql #count_sql, N'#total int OUTPUT', #total=#total OUTPUT
INSERT INTO #RegistrosFotograficos (DatabaseName, TableName, Total) VALUES (#banco_nome, #tabela_nome, #total);
FETCH NEXT FROM tabela_cursor INTO #tabela_nome
END
CLOSE tabela_cursor;
DEALLOCATE tabela_cursor;
FETCH NEXT FROM #banco_cursor INTO #banco_nome
END
CLOSE #banco_cursor;
DEALLOCATE #banco_cursor;
SELECT * FROM #RegistrosFotograficos
This will list all the tables in a given database and the number of rows in each. Notice the results are in a table named #results:
set nocount on
declare #curtable sysname
declare #prevtable sysname
declare #curcount int
declare #tsql varchar(500)
if object_ID('tempdb..#curtables','U') is not null
drop table #curtables
select name into #curtables
from sys.objects
where type='U'
order by 1
if object_id('tempdb..#results','U') is not null
drop table #results
create table #results(name sysname,numrows int)
select top 1 #curtable=name from #curtables order by name
while (1=1)
begin
set #tsql = 'select '''+quotename(#curtable) +''',count(*) numrows from '+quotename(#curtable)
print #tsql
insert into #results
exec (#tsql)
set #prevtable= #curtable
select top 1 #curtable = name
from #curtables
where name > #prevtable
order by name
if #curtable=#prevtable
break
end

Drop and re-create procedure if it exists in T-SQL not working

IF EXISTS ( SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'LOCATION') AND type IN (N'P', N'PC'))
DROP PROCEDURE [dbo].[LOCATION]
GO
CREATE PROCEDURE [dbo].[LOCATION]
#IP NVARCHAR(100)
AS
BEGIN
DECLARE #IPNumber BIGINT
SELECT #IPNumber = dbo.ConvertIp2Num(#IP)
SELECT [country_code],[country_name]
FROM [myDatabase].[dbo].[CountryIP]
WHERE #IPNumber BETWEEN ip_from AND ip_to
END
I have the above code to check if stored procedure LOCATION exists in the current database. I expect it to drop and re-create the procedure if it exists.
However, if the procedure exists the code is still executing and as a result i get the following error 'There is already an object named 'LOCATION' in the database.'
Why is that code failing to drop the procedure if it exists?
The same code works properly for a another procedure in the same database.
Try this (preferred method using a view):
IF EXISTS(SELECT 1
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_NAME = 'PRC_NAME'
AND SPECIFIC_SCHEMA = 'schema_name')
BEGIN
DROP PROCEDURE PRC_NAME
END
or this (not recommended using direct access to a system table):
IF EXISTS (SELECT 1
FROM SYS.PROCEDURES
WHERE NAME = 'PRC_NAME'
AND SCHEMA_NAME(SCHEMA_ID) = 'SCHEMA_NAME'
AND [TYPE] IN (N'P',N'PC'))
BEGIN
DROP PROCEDURE PRC_NAME
END
Why the first method is preferred you can find out for example in this question: SQL Server: should I use information_schema tables over sys tables?
This is kind of late, but others that end up here might want to check out the MSDN documentation that say you could use:
DROP PROCEDURE IF EXISTS dbo.uspMyProc;
GO
This is however available from SQL Server 2016 Community Technology Preview 3.3 (CTP 3.3).
You could use:
IF OBJECT_ID('MSL_GET_IP_LOCATION', 'P') IS NOT NULL
DROP PROCEDURE MSL_GET_IP_LOCATION
GO
Further thought on this is you will need to make sure you have unique names across all objects.
SQL Server -
Drop List of Stored Procedures if existed on Customer DB +
Copy List of Stored Procedures from master to another DB (recreate dynamically). P.S.: #TargetDBName=your DB.
I hope it will help someone
--Drop SPs from Customer DB if existed---
DECLARE #TargetDBName NVARCHAR(255)
SET #TargetDBName = DB_NAME()
DECLARE #SQL NVARCHAR(max)
SET #SQL = ''
DECLARE v CURSOR
FOR
SELECT [NAME]
FROM [Master].[sys].[procedures] p WITH(NOLOCK)
INNER JOIN [Master].sys.sql_modules m WITH(NOLOCK) ON p.object_id = m.object_id
WHERE p.[NAME] LIKE 'mySPs_list_%'
AND [type] = 'P'
OPEN v
FETCH NEXT
FROM v
INTO #sql
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = REPLACE(#sql, '''', '''''')
SET #sql = 'USE [' + #TargetDBName + ']; IF OBJECT_ID('''+#sql+''', ''P'') IS NOT NULL DROP PROCEDURE '+ #sql+';'
EXEC SP_EXECUTESQL #sql
FETCH NEXT
FROM v
INTO #sql
END
CLOSE v
DEALLOCATE v;
--COPY SPs from master to Another DB-------------
DECLARE c CURSOR
FOR
SELECT [Definition]
FROM [Master].[sys].[procedures] p
INNER JOIN [Master].sys.sql_modules m ON p.object_id = m.object_id
WHERE p.[NAME] LIKE 'mySPs_list_%'
AND [type] = 'P'
OPEN c
FETCH NEXT
FROM c
INTO #sql
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sql = REPLACE(#sql, '''', '''''')
SET #sql = 'USE [' + #TargetDBName + ']; EXEC(''' + #sql + ''')'
EXEC SP_EXECUTESQL #sql
FETCH NEXT
FROM c
INTO #sql
END
CLOSE c
DEALLOCATE c;

How to drop all tables in a SQL Server database?

I'm trying to write a script that will completely empty a SQL Server database. This is what I have so far:
USE [dbname]
GO
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DELETE ?'
When I run it in the Management Studio, I get:
Command(s) completed successfully.
but when I refresh the table list, they are all still there. What am I doing wrong?
You can also delete all tables from database using only MSSMS UI tools (without using SQL script). Sometimes this way can be more comfortable (especially if it is performed occasionally)
I do this step by step as follows:
Select 'Tables' on the database tree (Object Explorer)
Press F7 to open Object Explorer Details view
In this view select tables which have to be deleted (in this case all of them)
Keep pressing Delete until all tables have been deleted (you repeat it as many times as amount of errors due to key constraints/dependencies)
It doesn't work for me either when there are multiple foreign key tables.
I found that code that works and does everything you try (delete all tables from your database):
DECLARE #Sql NVARCHAR(500) DECLARE #Cursor CURSOR
SET #Cursor = CURSOR FAST_FORWARD FOR
SELECT DISTINCT sql = 'ALTER TABLE [' + tc2.TABLE_SCHEMA + '].[' + tc2.TABLE_NAME + '] DROP [' + rc1.CONSTRAINT_NAME + '];'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME =rc1.CONSTRAINT_NAME
OPEN #Cursor FETCH NEXT FROM #Cursor INTO #Sql
WHILE (##FETCH_STATUS = 0)
BEGIN
Exec sp_executesql #Sql
FETCH NEXT FROM #Cursor INTO #Sql
END
CLOSE #Cursor DEALLOCATE #Cursor
GO
EXEC sp_MSforeachtable 'DROP TABLE ?'
GO
You can find the post here. It is the post by Groker.
In SSMS:
Right click the database
Go to "Tasks"
Click "Generate Scripts"
In the "Choose Objects" section, select "Script entire database and all database objects"
In the "Set Scripting Options" section, click the "Advanced" button
On "Script DROP and CREATE" switch "Script CREATE" to "Script DROP" and press OK
Then, either save to file, clipboard, or new query window.
Run script.
Now, this will drop everything, including the database. Make sure to remove the code for the items you don't want dropped. Alternatively, in the "Choose Objects" section, instead of selecting to script entire database just select the items you want to remove.
The accepted answer doesn't support Azure. It uses an undocumented stored procedure "sp_MSforeachtable". If you get an "azure could not find stored procedure 'sp_msforeachtable" error when running or simply want to avoid relying on undocumented features (which can be removed or have their functionality changed at any point) then try the below.
This version ignores the entity framework migration history table "__MigrationHistory" and the "database_firewall_rules" which is an Azure table you will not have permission to delete.
Lightly tested on Azure. Do check to make this this has no undesired effects on your environment.
DECLARE #sql NVARCHAR(2000)
WHILE(EXISTS(SELECT 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY'))
BEGIN
SELECT TOP 1 #sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
EXEC(#sql)
PRINT #sql
END
WHILE(EXISTS(SELECT * from INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'))
BEGIN
SELECT TOP 1 #sql=('DROP TABLE ' + TABLE_SCHEMA + '.[' + TABLE_NAME + ']')
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'
EXEC(#sql)
PRINT #sql
END
Taken from:
https://edspencer.me.uk/2013/02/25/drop-all-tables-in-a-sql-server-database-azure-friendly/
http://www.sqlservercentral.com/blogs/sqlservertips/2011/10/11/remove-all-foreign-keys/
delete is used for deleting rows from a table. You should use drop table instead.
EXEC sp_msforeachtable 'drop table [?]'
/* Drop all Primary Key constraints */
DECLARE #name VARCHAR(128)
DECLARE #constraint VARCHAR(254)
DECLARE #SQL VARCHAR(254)
SELECT #name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)
WHILE #name IS NOT NULL
BEGIN
SELECT #constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND TABLE_NAME = #name ORDER BY CONSTRAINT_NAME)
WHILE #constraint is not null
BEGIN
SELECT #SQL = 'ALTER TABLE [dbo].[' + RTRIM(#name) +'] DROP CONSTRAINT [' + RTRIM(#constraint)+']'
EXEC (#SQL)
PRINT 'Dropped PK Constraint: ' + #constraint + ' on ' + #name
SELECT #constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' AND CONSTRAINT_NAME <> #constraint AND TABLE_NAME = #name ORDER BY CONSTRAINT_NAME)
END
SELECT #name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'PRIMARY KEY' ORDER BY TABLE_NAME)
END
GO
/* Drop all tables */
DECLARE #name VARCHAR(128)
DECLARE #SQL VARCHAR(254)
SELECT #name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name])
WHILE #name IS NOT NULL
BEGIN
SELECT #SQL = 'DROP TABLE [dbo].[' + RTRIM(#name) +']'
EXEC (#SQL)
PRINT 'Dropped Table: ' + #name
SELECT #name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > #name ORDER BY [name])
END
GO
You are almost right, use instead:
EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'
EXEC sp_msforeachtable 'DROP TABLE ?'
but second line you might need to execute more then once until you stop getting error:
Could not drop object 'dbo.table' because it is referenced by a FOREIGN KEY constraint.
Message:
Command(s) completed successfully.
means that all table were successfully deleted.
Short and sweet:
USE YOUR_DATABASE_NAME
-- Disable all referential integrity constraints
EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
-- Drop all PKs and FKs
declare #sql nvarchar(max)
SELECT #sql = STUFF((SELECT '; ' + 'ALTER TABLE ' + Table_Name +' drop constraint ' + Constraint_Name from Information_Schema.CONSTRAINT_TABLE_USAGE ORDER BY Constraint_Name FOR XML PATH('')),1,1,'')
EXECUTE (#sql)
GO
-- Drop all tables
EXEC sp_MSforeachtable 'DROP TABLE ?'
GO
Spot on!!
You can use below query to remove all the tables from database
EXEC sp_MSforeachtable #command1 = "DROP TABLE ?"
Happy coding !
Seems the command should be without the square blanket
EXEC sp_msforeachtable 'drop table ?'
The fasted way is:
New Database Diagrams
Add all table
Ctrl + A to select all
Right Click "Remove from Database"
Ctrl + S to save
Enjoy
For me, the easiest way:
--First delete all constraints
DECLARE #sql NVARCHAR(MAX);
SET #sql = N'';
SELECT #sql = #sql + N'
ALTER TABLE ' + QUOTENAME(s.name) + N'.'
+ QUOTENAME(t.name) + N' DROP CONSTRAINT '
+ QUOTENAME(c.name) + ';'
FROM sys.objects AS c
INNER JOIN sys.tables AS t
ON c.parent_object_id = t.[object_id]
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE c.[type] IN ('D','C','F','PK','UQ')
ORDER BY c.[type];
EXEC sys.sp_executesql #sql;
-- Then drop all tables
exec sp_MSforeachtable 'DROP TABLE ?'
Azure SQL + tables (with constraints) in a different schema than dbo + ipv6_database_firewall_rules condition.
This is a little extension for https://stackoverflow.com/a/43128914/4510954 answer.
DECLARE #sql NVARCHAR(2000)
WHILE(EXISTS(SELECT 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY'))
BEGIN
SELECT TOP 1 #sql=('ALTER TABLE ' + CONSTRAINT_SCHEMA + '.[' + TABLE_NAME + '] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
EXEC(#sql)
PRINT #sql
END
WHILE(EXISTS(SELECT * from INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules' AND TABLE_NAME != 'ipv6_database_firewall_rules'))
BEGIN
SELECT TOP 1 #sql=('DROP TABLE ' + CONSTRAINT_SCHEMA + '.[' + TABLE_NAME + ']')
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_NAME != '__MigrationHistory' AND TABLE_NAME != 'database_firewall_rules'
EXEC(#sql)
PRINT #sql
END
How about dropping the entire database and then creating it again? This works for me.
DROP DATABASE mydb;
CREATE DATABASE mydb;
For Temporal Tables it is a bit more complicated due to the fact there may be some foreign keys and also exception:
Drop table operation failed on table XXX because it is not a supported operation on system-versioned temporal tables
What you can use is:
-- Disable constraints (foreign keys)
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
-- Disable system versioning (temporial tables)
EXEC sp_MSForEachTable '
IF OBJECTPROPERTY(object_id(''?''), ''TableTemporalType'') = 2
ALTER TABLE ? SET (SYSTEM_VERSIONING = OFF)
'
GO
-- Removing tables
EXEC sp_MSForEachTable 'DROP TABLE ?'
GO
I know this is an old post now but I have tried all the answers on here on a multitude of databases and I have found they all work sometimes but not all of the time for various (I can only assume) quirks of SQL Server.
Eventually I came up with this. I have tested this everywhere (generally speaking) I can and it works (without any hidden store procedures).
For note mostly on SQL Server 2014. (but most of the other versions I tried it also seems to worked fine).
I have tried while loops and nulls etc etc, cursors and various other forms but they always seem to fail on some databases but not others for no obvious reason.
Getting a count and using that to iterate always seems to work on everything Ive tested.
USE [****YOUR_DATABASE****]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
-- Drop all referential integrity constraints --
-- Drop all Primary Key constraints. --
DECLARE #sql NVARCHAR(296)
DECLARE #table_name VARCHAR(128)
DECLARE #constraint_name VARCHAR(128)
SET #constraint_name = ''
DECLARE #row_number INT
SELECT #row_number = Count(*) FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME
WHILE #row_number > 0
BEGIN
BEGIN
SELECT TOP 1 #table_name = tc2.TABLE_NAME, #constraint_name = rc1.CONSTRAINT_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc1
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc2 ON tc2.CONSTRAINT_NAME = rc1.CONSTRAINT_NAME
AND rc1.CONSTRAINT_NAME > #constraint_name
ORDER BY rc1.CONSTRAINT_NAME
SELECT #sql = 'ALTER TABLE [dbo].[' + RTRIM(#table_name) +'] DROP CONSTRAINT [' + RTRIM(#constraint_name)+']'
EXEC (#sql)
PRINT 'Dropped Constraint: ' + #constraint_name + ' on ' + #table_name
SET #row_number = #row_number - 1
END
END
GO
-- Drop all tables --
DECLARE #sql NVARCHAR(156)
DECLARE #name VARCHAR(128)
SET #name = ''
DECLARE #row_number INT
SELECT #row_number = Count(*) FROM sysobjects WHERE [type] = 'U' AND category = 0
WHILE #row_number > 0
BEGIN
SELECT #name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > #name ORDER BY [name])
SELECT #sql = 'DROP TABLE [dbo].[' + RTRIM(#name) +']'
EXEC (#sql)
PRINT 'Dropped Table: ' + #name
SET #row_number = #row_number - 1
END
GO
sp_msforeachtable is not available in Azure SQL
For Azure SQL:
This query will drop Foreign Key constraints
DECLARE #Name VARCHAR(200)
DECLARE #Constraint VARCHAR(300)
DECLARE #SQL VARCHAR(300)
SELECT #Name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME)
WHILE #Name is not null
BEGIN
SELECT #Constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND TABLE_NAME = #Name ORDER BY CONSTRAINT_NAME)
WHILE #Constraint IS NOT NULL
BEGIN
SELECT #SQL = 'ALTER TABLE [dbo].[' + RTRIM(#Name) +'] DROP CONSTRAINT [' + RTRIM(#Constraint) +']'
EXEC (#SQL)
PRINT 'Dropped FK Constraint: ' + #Constraint + ' on ' + #Name
SELECT #Constraint = (SELECT TOP 1 CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' AND CONSTRAINT_NAME <> #Constraint AND TABLE_NAME = #Name ORDER BY CONSTRAINT_NAME)
END
SELECT #Name = (SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE constraint_catalog=DB_NAME() AND CONSTRAINT_TYPE = 'FOREIGN KEY' ORDER BY TABLE_NAME)
END
GO
This will drop all the tables from the database
DECLARE #Name VARCHAR(200)
DECLARE #SQL VARCHAR(300)
SELECT #Name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 ORDER BY [name])
WHILE #Name IS NOT NULL
BEGIN
SELECT #SQL = 'DROP TABLE [dbo].[' + RTRIM(#name) +']' /*here you can change schema if it is different from dbo*/
EXEC (#SQL)
PRINT 'Dropped Table: ' + #Name
SELECT #Name = (SELECT TOP 1 [name] FROM sysobjects WHERE [type] = 'U' AND category = 0 AND [name] > #Name ORDER BY [name])
END
GO

Resources