Correct way to drop a table in SQL Server - sql-server

What is the best way to drop a table? The code I have does it two different ways. It will be dropped every week when I do a bulk insert. Thanks.
Like this?
IF EXISTS (SELECT *
FROM DBO.SYSOBJECTS
WHERE ID = OBJECT_ID(N'[DBO].[ZIP]') AND OBJECTPROPERTY(ID, N'IsUserTable') = 1)
DROP TABLE [DBO].[ZIP]
Or this?
DROP TABLE DEID.DBO.ZIP

The second method will throw an error if the table doesn't exist, or if other database objects depend on it.
The first one will not throw an error if the table doesn't exist, but it will still throw an error if other database objects depend on it.
Check out this answers on Stack-overflow:
DROP IF EXISTS VS DROP?
How to drop a table if it exists?

Related

How can we know what kind of a constraint was dropped in Sql Server without maintaining our own copy of sys.objects?

So, I created the following DDL trigger:
CREATE TRIGGER [BeforeAlterTable] ON DATABASE FOR ALTER_TABLE
AS
BEGIN
SELECT * FROM sys.objects WHERE Name = 'PK_MyTable'
END
The problem is that when PK_MyTable primary key is dropped, the trigger outputs empty result set - the information about the primary key is already gone from the sys.objects view.
This could be resolved by maintaining our own copy of sys.objects (a subset of type = 'PK' would suffice), but I would like to avoid it.
Anyway to make it work?
EDIT 1
Note that the question is about deducing the kind of the constraint, not its name or the table it belongs too. These are found in the EVENTDATA() function result. What is not found there is the kind of the constraint.

Exception after dropping table

If I execute a procedure that drops a table and then recreate it using 'SELECT INTO'.
IF that procedure raises an exception after dropping the table, does table dropping take place or not?
Unless you wrap them in a transaction,table will be dropped since each statement will be considered as an implicit transaction..
below are some tests
create table t1
(
id int not null primary key
)
drop table t11
insert into t1
select 1 union all select 1
table t11 will be dropped,even though insert will raise an exception..
one more example..
drop table orderstest
print 'dropped table'
waitfor delay '00:00:05'
select * into orderstest
from Orders
now after 2 seconds,kill session and you can still see orderstest being dropped
I checked with some other statements other than select into ,i don't see a reason why select into will behave differently and this applies even if you wrap statements in a stored proc..
IF you want to rollback all,use a transaction or more better use set xact_Abort on
Yes, the dropped table will be gone. I have had this issue when I script a new primary key. Depending on the table, it saves all the data to a table variable in memory, drops the table, creates a new one with the new pk, then loads the data. If the data violates the new pk, the statement fails and the table variable is dropped leaving me with a new table and no data.
My practice is to create the new table with a slightly different name, load the data, change both table names in a statement, then once all the data is confirmed loaded, drop the original table.

IF Exists MSSQL always errors

I'm trying to drop a table if it exists.
I created a table, that worked fine. I can drop the table with the DROP TABLE command. What I can't do is any form of this:
DROP TABLE IF EXISTS customer;
In fact, I can't seem to get any form of IF EXISTS to work at all. I went to the MS website and looked up how to do this, and their example won't even run:
CREATE TABLE T1 (Col1 int);
GO
DROP TABLE IF EXISTS T1;
GO
DROP TABLE IF EXISTS T1;
Any ideas?
According to the documentation, the IF EXISTS clause is only allowed in Azure SQL Database and SQL Server 2016 or later. So it seems you are using SQL Server 2014 or earlier.
You'll need to first check that the table exists in earlier versions. One method is checking for a OBJECT_ID that is NOT NULL:
IF OBJECT_ID(N'dbo.customer', 'U') IS NOT NULL DROP TABLE dbo.customer;

Referencing Columns on the Inserted Table T-SQL

So, I'm trying to create a trigger that will throw an error on inserting data if a foreign key code is not valid. I have two tables, Publisher and Title. Title has a publisher code on it, as does Publisher. I have the trigger on my Title for insert, and I am currently doing an if not exists and selecting the Publisher row where the code is equal to the inserted row's publisher code. I don't know if this is the right way to do it, and probably not, as SQL is giving me a "multi-part identifier Inserted.PublisherCode could not be found" error. Any help you guys could give would be appreciated. Thanks.
go
create trigger TR_Title_PublisherCode_Insert
on title
for Insert
as
if not exists(select * from Publisher where PublisherCode = Inserted.PublisherCode)
begin
raiserror('Publisher does not exist', 16, 1)
rollback tran
end
INSERTED and DELETED are table too
So you have to do this:
if not exists(
select * from Publisher
where PublisherCode in (SELECT PublisherCode FROM inserted)
)
By the way, as hkf said, if you identified PublisherCode AS foreign key, you won't have a need to make trigger

How do I add the identity property to an existing column in SQL Server

In SQL Server (in my case, 2005) how can I add the identity property to an existing table column using T-SQL?
Something like:
alter table tblFoo
alter column bar identity(1,1)
I don't beleive you can do that. Your best bet is to create a new identity column and copy the data over using an identity insert command (if you indeed want to keep the old values).
Here is a decent article describing the process in detail:
http://www.mssqltips.com/tip.asp?tip=1397
The solution posted by Vikash doesn't work; it produces an "Incorrect syntax" error in SQL Management Studio (2005, as the OP specified). The fact that the "Compact Edition" of SQL Server supports this kind of operation is just a shortcut, because the real process is more like what Robert & JohnFX said--creating a duplicate table, populating the data, renaming the original & new tables appropriately.
If you want to keep the values that already exist in the field that needs to be an identity, you could do something like this:
CREATE TABLE tname2 (etc.)
INSERT INTO tname2 FROM tname1
DROP TABLE tname1
CREATE TABLE tname1 (with IDENTITY specified)
SET IDENTITY_INSERT tname1 ON
INSERT INTO tname1 FROM tname2
SET IDENTITY_INSERT tname1 OFF
DROP tname2
Of course, dropping and re-creating a table (tname1) that is used by live code is NOT recommended! :)
Is the table populated? If not drop and recreate the table.
If it is populated what values already exist in the column? If they are values you don't want to keep.
Create a new table as you desire it, load the records from your old table into your new talbe and let the database populate the identity column as normal. Rename your original table and rename the new one to the correct name :).
Finally if the column you wish to make identity currently contains primary key values and is being referenced already by other tables you will need to totally re think if you're sure this is what you want to do :)
There is no direct way of doing this except:
A) through SQL i.e.:
-- make sure you have the correct CREATE TABLE script ready with IDENTITY
SELECT * INTO abcTable_copy FROM abcTable
DROP TABLE abcTable
CREATE TABLE abcTable -- this time with the IDENTITY column
SET IDENTITY_INSERT abcTable ON
INSERT INTO abcTable (..specify all columns!) FROM (..specify all columns!) abcTable_copy
SET INDENTITY_INSERT abcTable OFF
DROP TABLE abcTable_copy
-- I would suggest to verify the contents of both tables
-- before dropping the copy table
B) Through MSSMS which will do exactly the same in the background but will less fat-fingering.
In the MSSMS Object Explorer right click the table you need to modify
Select "design" Select the column you'd like to add IDENTITY to
Change the identity setting from NO -> YES (possibly seed)
Ctr+S the table
This will drop and recreate the table with all original data in it.
If you get a warning:
Go to MSSMS Tools -> Options -> Designers -> Table and database Designers
and uncheck the option "Prevent saving changes that require table re-creation"
Things to be careful about:
your DB has enough disk space before you do this
the DB is not in use (especially the table you are changing)
make sure to backup your DB before doing it
if the table has a lot of data (over 1G) try it somewhere else first
before using in real DB
Create a New Table
SELECT * INTO Table_New FROM Table_Current WHERE 1 = 0;
Drop Column from New Table
Alter table Table_New drop column id;
Add column with identity
Alter table Table_New add id int primary key identity;
Get All Data in New Table
SET IDENTITY_INSERT Table_New ON;
INSERT INTO Table_New (id, Name,CreatedDate,Modified)
SELECT id, Name,CreatedDate,Modified FROM Table_Current;
SET IDENTITY_INSERT Table_New OFF;
Drop old Table
drop table Table_Current;
Rename New Table as old One
EXEC sp_rename 'Table_New', 'Table_Current';
alter table tablename
alter column columnname
add Identity(100,1)

Resources