How to drop a table if it exists? - sql-server

The table name is Scores.
Is it correct to do the following?
IF EXISTS(SELECT *
FROM dbo.Scores)
DROP TABLE dbo.Scores

Is it correct to do the following?
IF EXISTS(SELECT *
FROM dbo.Scores)
DROP TABLE dbo.Scores
No. That will drop the table only if it contains any rows (and will raise an error if the table does not exist).
Instead, for a permanent table you can use
IF OBJECT_ID('dbo.Scores', 'U') IS NOT NULL
DROP TABLE dbo.Scores;
Or, for a temporary table you can use
IF OBJECT_ID('tempdb.dbo.#TempTableName', 'U') IS NOT NULL
DROP TABLE #TempTableName;
SQL Server 2016+ has a better way, using DROP TABLE IF EXISTS …. See the answer by #Jovan.

From SQL Server 2016 you can use
DROP TABLE IF EXISTS dbo.Scores
Reference: DROP IF EXISTS - new thing in SQL Server 2016
It will be in SQL Azure Database soon.

The ANSI SQL/cross-platform way is to use the INFORMATION_SCHEMA, which was specifically designed to query meta data about objects within SQL databases.
if exists (select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = 'Scores' AND TABLE_SCHEMA = 'dbo')
drop table dbo.Scores;
Most modern RDBMS servers provide, at least, basic INFORMATION_SCHEMA support, including: MySQL, Postgres, Oracle, IBM DB2, and Microsoft SQL Server 7.0 (and greater).

Have seen so many that don't really work.
when a temp table is created it must be deleted from the tempdb!
The only code that works is:
IF OBJECT_ID('tempdb..#tempdbname') IS NOT NULL --Remove dbo here
DROP TABLE #tempdbname -- Remoeve "tempdb.dbo"

In SQL Server 2016 (13.x) and above
DROP TABLE IF EXISTS dbo.Scores
In earlier versions
IF OBJECT_ID('dbo.Scores', 'U') IS NOT NULL
DROP TABLE dbo.Scores;
U is your table type

Or:
if exists (select * from sys.objects where name = 'Scores' and type = 'u')
drop table Scores

I hope this helps:
begin try drop table #tempTable end try
begin catch end catch

I wrote a little UDF that returns 1 if its argument is the name of an extant table, 0 otherwise:
CREATE FUNCTION [dbo].[Table_exists]
(
#TableName VARCHAR(200)
)
RETURNS BIT
AS
BEGIN
If Exists(select * from INFORMATION_SCHEMA.TABLES where TABLE_NAME = #TableName)
RETURN 1;
RETURN 0;
END
GO
To delete table User if it exists, call it like so:
IF [dbo].[Table_exists]('User') = 1 Drop table [User]

Simple is that:
IF OBJECT_ID(dbo.TableName, 'U') IS NOT NULL
DROP TABLE dbo.TableName
where dbo.TableName is your desired table and 'U' is type of your table.

IF EXISTS (SELECT NAME FROM SYS.OBJECTS WHERE object_id = OBJECT_ID(N'Scores') AND TYPE in (N'U'))
DROP TABLE Scores
GO

SQL Server 2016 and above the best and simple one is
DROP TABLE IF EXISTS [TABLE NAME]
Ex:
DROP TABLE IF EXISTS dbo.Scores
if suppose the above one is not working then you can use the below one
IF OBJECT_ID('dbo.Scores', 'u') IS NOT NULL
DROP TABLE dbo.Scores;

I use:
if exists (select *
from sys.tables
where name = 'tableName'
and schema_id = schema_id('dbo'))
begin
drop table dbo.tableName
end

Make sure to use cascade constraint at the end to automatically drop all objects that depend on the table (such as views and projections).
drop table if exists tableName cascade;

If you use long codes and want to write less for temporary table create this procedure:
CREATE PROCEDURE MF_DROP (#TEMP AS VARCHAR(100)) AS
EXEC('IF OBJECT_ID(''TEMPDB.DBO.' + #TEMP + ''', ''U'') IS NOT NULL DROP TABLE ' + #TEMP)
In execution:
EXEC MF_DROP #A
CREATE TABLE #A (I INT) ....

A better visual and easy way, if you are using Visual Studio, just open from menu bar,
View -> SQL Server Object Explorer
it should open like shown here
Select and Right Click the Table you wish to delete, then delete. Such a screen should be displayed. Click Update Database to confirm.
This method is very safe as it gives you the feedback and will warn of any relations of the deleted table with other tables.

Related

T-SQL equivalent of C++ #define

I have an SQL-Script for changing the source tables of multiple views at once. To do so I would like to have something like
#define source theSourceTable
instead of finding and replacing the parts I need. My understanding is that this isn't possible with local variables but is there another way?
Like I mentioned in the comments, a SYNONYM, seems to the right idea here. As we have very little to work with, here is an overly simplified example:
USE Sandbox;
GO
--Create some sample tables
CREATE TABLE dbo.MyTable1 (MyColumn int);
INSERT INTO dbo.MyTable1 (MyColumn)
VALUES (1),(2);
CREATE TABLE dbo.MyTable2 (MyColumn int);
INSERT INTO dbo.MyTable2 (MyColumn)
VALUES (3),(4);
GO
--Create synonyms
CREATE SYNONYM dbo.MyTableA FOR dbo.MyTable1;
CREATE SYNONYM dbo.MyTableB FOR dbo.MyTable1;
GO
--Create views
CREATE VIEW MyView1 AS
SELECT MyColumn, 'View1' AS ObjectName
FROM dbo.MyTableA;
GO
CREATE VIEW MyView2 AS
SELECT MyColumn, 'View2' AS ObjectName
FROM dbo.MyTableB;
GO
CREATE VIEW MyView3 AS
SELECT A.MyColumn AS AColumn,
B.MyColumn AS BColumn,
'View3' AS ObjectName
FROM dbo.MyTableA A
CROSS JOIN dbo.MyTableB B;
GO
--Check data
SELECT *
FROM dbo.MyView1;
SELECT *
FROM dbo.MyView2;
SELECT *
FROM dbo.MyView3;
GO
--Create a new table
CREATE TABLE dbo.MyTable3 (MyColumn int);
INSERT INTO dbo.MyTable3 (MyColumn)
VALUES (5),(6);
GO
--Alter the synonyms
DROP SYNONYM dbo.MyTableA;
CREATE SYNONYM dbo.MyTableA FOR dbo.MyTable2;
DROP SYNONYM dbo.MyTableB;
CREATE SYNONYM dbo.MyTableB FOR dbo.MyTable3;
GO
--Check views again:
--Check data
SELECT *
FROM dbo.MyView1;
SELECT *
FROM dbo.MyView2;
SELECT *
FROM dbo.MyView3;
GO
--Clean up
DROP VIEW dbo.MyView1;
DROP VIEW dbo.MyView2;
DROP VIEW dbo.MyView3;
DROP SYNONYM dbo.MyTableA;
DROP SYNONYM dbo.MyTableB;
DROP TABLE dbo.MyTable1;
DROP TABLE dbo.MyTable2;
DROP TABLE dbo.MyTable3;
You will need to edit the existing DDL of all your views once, to use the new synonym's name instead, but after that you can simply recreate the synonyms and they will all be updated.
You might be able to use SQLCMD mode (activate with ALT-Q-M or toggle it in the Query menu in SSMS).
:SETVAR MyTable SomeTableName
CREATE OR ALTER VIEW dbo.myView
AS
SELECT * FROM dbo.$(MyTable)
GO
This will end up with a view that selects * from SomeTableName
Alternatively you can possibly use dynamic sql
DECLARE #sql VARCHAR(MAX)
DECLARE #myTable VARCHAR(100) = 'SomeTableName'
SET #sql = 'CREATE OR ALTER VIEW dbo.myView
AS
SELECT * FROM dbo.' + #myTable
EXEC(#sql)
which has the same end result.
(CREATE OR ALTER is SQL2016 syntactic sugar, if you are on an older version adjust accordingly)

Describe Temp table columns in SQL Server

I have this script:
CREATE TABLE #TempTable (Id int)
ALTER TABLE #TempTable ADD [IdKey] INT
ALTER TABLE #TempTable ADD [ProviderName] NVARCHAR(100)
SELECT *
FROM tempdb.sys.columns
WHERE [object_id] = OBJECT_ID(N'tempdb..#TempTable');
I need to read the columns of this temp table and create another temp table based on the previous one.
Why when I do the select of tempdb.sys.columns, the ProviderName length is 200 instead of 100?
With this simple query it's possible to copy the temp table structure:
SELECT *
INTO #NewTempTable
FROM #TempTable
WHERE 1 = 0
Using this will solve the issue:
SELECT * FROM [tempdb].[sys].[dm_exec_describe_first_result_set] (N'SELECT Id, [IdKey], [ProviderName] FROM #temptable', null, 0);
Clone Temporary Table Structure to New Physical Table in SQL Server
we will see how to Clone Temporary Table Structure to New Physical Table in SQL Server.This is applicable for both Azure SQL db and on-premises.
Demo SQL Script
IF OBJECT_ID('TempDB..#TempTable') IS NOT NULL
DROP TABLE #TempTable;
SELECT 1 AS ID,'Arul' AS Names
INTO
#TempTable;
SELECT * FROM #TempTable;
METHOD 1
SELECT * INTO TempTable1 FROM #TempTable WHERE 1=0;
EXEC SP_HELP TempTable1;
METHOD 2
SELECT TOP 0 * INTO TempTable1 FROM #TempTable;
EXEC SP_HELP TempTable1;

How to create a table in sql server like other table?

I want to create a table like another table in SQL Server.
In Postgres I used to create it with this request:
CREATE TABLE IF NOT EXISTS table2 (LIKE table1 INCLUDING ALL) INHERITS (table1)
Something like this should work:
IF OBJECT_ID('table1', 'U') IS NULL BEGIN
SELECT TOP 0 * INTO table1 FROM table2
END
This will clone the column definition of table2 in table1 without inserting any data (because of the top 0).
Then you have to create the PK, UK, FK for the table1. For this purpose you can check: https://www.mssqltips.com/sqlservertip/3443/script-all-primary-keys-unique-constraints-and-foreign-keys-in-a-sql-server-database-using-tsql/
With this resource you can generate an ALTER TABLE script to add all PK, UK, FK in a variable and run it like:
DECLARE #sqlCommand nvarchar(1000)
EXECUTE sp_executesql #sqlCommand
SELECT *
INTO table2
FROM table1 where 1=2
SELECT * = select all columns
INTO= place of set
FROM = place to lookup,
WHERE 1=2 = filter criteria
select top 0 * into x from y
will give you an empty shell of a table with no data exactly defined as the original table minus all the indexes , constraints etc

How to check if a Constraint exists in Sql server?

I have this sql:
ALTER TABLE dbo.ChannelPlayerSkins
DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
but apparently, on some other databases we use, the constraint has a different name. How do I check if there's a constraint with the name FK_ChannelPlayerSkins_Channels.
try this:
SELECT
*
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_NAME ='FK_ChannelPlayerSkins_Channels'
-- EDIT --
When I originally answered this question, I was thinking "Foreign Key" because the original question asked about finding "FK_ChannelPlayerSkins_Channels". Since then many people have commented on finding other "constraints" here are some other queries for that:
--Returns one row for each CHECK, UNIQUE, PRIMARY KEY, and/or FOREIGN KEY
SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME='XYZ'
--Returns one row for each FOREIGN KEY constrain
SELECT *
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
WHERE CONSTRAINT_NAME='XYZ'
--Returns one row for each CHECK constraint
SELECT *
FROM INFORMATION_SCHEMA.CHECK_CONSTRAINTS
WHERE CONSTRAINT_NAME='XYZ'
here is an alternate method
--Returns 1 row for each CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY, and/or DEFAULT
SELECT
OBJECT_NAME(OBJECT_ID) AS NameofConstraint
,SCHEMA_NAME(schema_id) AS SchemaName
,OBJECT_NAME(parent_object_id) AS TableName
,type_desc AS ConstraintType
FROM sys.objects
WHERE type_desc LIKE '%CONSTRAINT'
AND OBJECT_NAME(OBJECT_ID)='XYZ'
If you need even more constraint information, look inside the system stored procedure master.sys.sp_helpconstraint to see how to get certain information. To view the source code using SQL Server Management Studio get into the "Object Explorer". From there you expand the "Master" database, then expand "Programmability", then "Stored Procedures", then "System Stored Procedures". You can then find "sys.sp_helpconstraint" and right click it and select "modify". Just be careful to not save any changes to it. Also, you can just use this system stored procedure on any table by using it like EXEC sp_helpconstraint YourTableNameHere.
Easiest way to check for the existence of a constraint (and then do something such as drop it if it exists) is to use the OBJECT_ID() function...
IF OBJECT_ID('dbo.[CK_ConstraintName]', 'C') IS NOT NULL
ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName
OBJECT_ID can be used without the second parameter ('C' for check constraints only) and that may also work, but if your constraint name matches the name of other objects in the database you may get unexpected results.
IF OBJECT_ID('dbo.[CK_ConstraintName]') IS NOT NULL
ALTER TABLE dbo.[tablename] DROP CONSTRAINT CK_ConstraintName
OBJECT_ID can also be used with other "constraints" such as Foreign Key constraints or Primary Key constraints, etc. For best results, always include the appropriate object type as the second parameter for the OBJECT_ID function:
Constraint Object Types:
C = CHECK constraint
D = DEFAULT (constraint or stand-alone)
F = FOREIGN KEY constraint
PK = PRIMARY KEY constraint
R = Rule (old-style, stand-alone)
UQ = UNIQUE constraint
Also note that the schema is often required. The schema of constraints generally takes the schema of the parent table.
Failure to put your constraints (or whatever you are checking) in brackets when using this method may also cause a false negative -- if your object uses unusual characters (such as a .), the brackets are required.
If you are looking for other type of constraint, e.g. defaults, you should use different query
(From How do I find a default constraint using INFORMATION_SCHEMA? answered by devio). Use:
SELECT * FROM sys.objects WHERE type = 'D' AND name = #name
to find a default constraint by name.
I've put together different 'IF not Exists" checks in my post "DDL 'IF not Exists" conditions to make SQL scripts re-runnable"
IF (OBJECT_ID('FK_ChannelPlayerSkins_Channels') IS NOT NULL)
Are you looking at something like this, below is tested in SQL Server 2005
SELECT * FROM sys.check_constraints WHERE
object_id = OBJECT_ID(N'[dbo].[CK_accounts]') AND
parent_object_id = OBJECT_ID(N'[dbo]. [accounts]')
Just something to watch out for......
In SQL Server 2008 R2 SSMS, the "Script Constraint as -> DROP And CREATE To" command produces T-SQL like below
USE [MyDatabase]
GO
IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[DEF_Detail_IsDeleted]') AND type = 'D')
BEGIN
ALTER TABLE [Patient].[Detail] DROP CONSTRAINT [DEF_Detail_IsDeleted]
END
GO
USE [MyDatabase]
GO
ALTER TABLE [Patient].[Detail] ADD CONSTRAINT [DEF_Detail_IsDeleted] DEFAULT ((0)) FOR [IsDeleted]
GO
Out of the box, this script does NOT drop the constraint because the SELECT returns 0 rows. (see post Microsoft Connect).
The name of the default constraint is wrong but I gather it also has something to do with the OBJECT_ID function because changing the name doesn't fix the problem.
To fix this, I removed the usage of OBJECT_ID and used the default constraint name instead.
(SELECT * FROM dbo.sysobjects WHERE [name] = (N'DEF_Detail_IsDeleted') AND type = 'D')
I use the following query to check for an existing constraint before I create it.
IF (NOT EXISTS(SELECT 1 FROM sysconstraints WHERE OBJECT_NAME(constid) = 'UX_CONSTRAINT_NAME' AND OBJECT_NAME(id) = 'TABLE_NAME')) BEGIN
...
END
This queries for the constraint by name targeting a given table name. Hope this helps.
IF EXISTS(SELECT 1 FROM sys.foreign_keys WHERE parent_object_id = OBJECT_ID(N'dbo.TableName'))
BEGIN
ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME
END
IF EXISTS(SELECT TOP 1 1 FROM sys.default_constraints WHERE parent_object_id = OBJECT_ID(N'[dbo].[ChannelPlayerSkins]') AND name = 'FK_ChannelPlayerSkins_Channels')
BEGIN
DROP CONSTRAINT FK_ChannelPlayerSkins_Channels
END
GO
INFORMATION_SCHEMA is your friend. It has all kinds of views that show all kinds of schema information. Check your system views. You will find you have three views dealing with constraints, one being CHECK_CONSTRAINTS.
I use this to check for and remote constraints on a column. It should have everything you need.
DECLARE
#ps_TableName VARCHAR(300)
, #ps_ColumnName VARCHAR(300)
SET #ps_TableName = 'mytable'
SET #ps_ColumnName = 'mycolumn'
DECLARE c_ConsList CURSOR LOCAL STATIC FORWARD_ONLY FOR
SELECT
'ALTER TABLE ' + RTRIM(tb.name) + ' drop constraint ' + sco.name AS csql
FROM
sys.Objects tb
INNER JOIN sys.Columns tc on (tb.Object_id = tc.object_id)
INNER JOIN sys.sysconstraints sc ON (tc.Object_ID = sc.id and tc.column_id = sc.colid)
INNER JOIN sys.objects sco ON (sc.Constid = sco.object_id)
where
tb.name=#ps_TableName
AND tc.name=#ps_ColumnName
OPEN c_ConsList
FETCH c_ConsList INTO #ls_SQL
WHILE (##FETCH_STATUS = 0) BEGIN
IF RTRIM(ISNULL(#ls_SQL, '')) <> '' BEGIN
EXECUTE(#ls_SQL)
END
FETCH c_ConsList INTO #ls_SQL
END
CLOSE c_ConsList
DEALLOCATE c_ConsList
SELECT tabla.name as Tabla,
restriccion.name as Restriccion,
restriccion.type as Tipo,
restriccion.type_desc as Tipo_Desc
FROM {DATABASE_NAME}.sys.objects tabla
INNER JOIN {DATABASE_NAME}.sys.objects restriccion
ON tabla.object_id = restriccion.parent_object_id
WHERE tabla.type = 'U' - Solo tablas creadas por el usuario.
AND restriccion.type = 'UQ' --Tipo de Restriccion UNIQUE
ORDER BY tabla.name, restriccion.type_desc
You can use the one above with one caveat:
IF EXISTS(
SELECT 1 FROM sys.foreign_keys
WHERE parent_object_id = OBJECT_ID(N'dbo.TableName')
AND name = 'CONSTRAINTNAME'
)
BEGIN
ALTER TABLE TableName DROP CONSTRAINT CONSTRAINTNAME
END
Need to use the name = [Constraint name] since a table may have multiple foreign keys and still not have the foreign key being checked for
In mySql you need to make sure you are querying the right database!
Hence table_schema=DATABASE()
Here are my functions using knex to check if a specific Foreign Key or Index defined in specific database and table
const isFKExists = async (knex, tableName, fkName) => {
const result = await knex.raw(
`SELECT COUNT(*) AS 'isExists' FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_schema=DATABASE() AND table_name='${tableName}' AND CONSTRAINT_NAME='${fkName}' AND CONSTRAINT_TYPE = 'FOREIGN KEY'`
)
return (result[0][0].isExists === 1)
}
const isIndexExists = async (knex, tableName, indexName) => {
const result = await knex.raw(
`SELECT COUNT(*) AS 'isExists' FROM INFORMATION_SCHEMA.STATISTICS WHERE table_schema=DATABASE() AND table_name='${tableName}' AND index_name='${indexName}'`
)
return (result[0][0].isExists > 0)
}
Enjoy 😊
As of SQL Server 2016, you can just use the IF EXISTS keywords.
ALTER TABLE dbo.ChannelPlayerSkins
DROP CONSTRAINT IF EXISTS FK_ChannelPlayerSkins_Channels
I'm using SQL Server 2019, but this mentions that it was available since SQL Server 2016.
The SQL Server docs mention it here under the ALTER TABLE page, and not under this Delete Check Constraints page. I'm not sure why.
IF EXISTS
Applies to: SQL Server (SQL Server 2016 (13.x) and later) and Azure SQL Database.
Conditionally drops the column or constraint only if it already exists.

What's the best way to determine if a temporary table exists in SQL Server?

When writing a T-SQL script that I plan on re-running, often times I use temporary tables to store temporary data. Since the temp table is created on the fly, I'd like to be able to drop that table only if it exists (before I create it).
I'll post the method that I use, but I'd like to see if there is a better way.
IF Object_Id('TempDB..#TempTable') IS NOT NULL
BEGIN
DROP TABLE #TempTable
END
The OBJECT_ID function returns the internal object id for the given object name and type. 'tempdb..#t1' refers to the table #t1 in the tempdb database. 'U' is for user-defined table.
IF OBJECT_ID('tempdb..#t1', 'U') IS NOT NULL
DROP TABLE #t1
CREATE TABLE #t1
(
id INT IDENTITY(1,1),
msg VARCHAR(255)
)
SELECT name
FROM sysobjects
WHERE type = 'U' AND name = 'TempTable'

Resources