11
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.

12
  • try object_id = OBJECT_ID(N'[dbo].[MSL_GET_IP_LOCATION]') Commented Oct 30, 2014 at 7:33
  • @artm same error. The same code works for properly for a another procedure in the same database. Commented Oct 30, 2014 at 7:35
  • 1
    Does select return anything if you exclude AND type IN (N'P', N'PC') ? Commented Oct 30, 2014 at 7:37
  • 1
    OK, looks like i got it working, if i put GO after BEGIN .....END on all procedures definitions, they all run successfully. Commented Oct 30, 2014 at 8:05
  • 1
    Possible duplicate of How to check if a stored procedure exists before creating it Commented Jun 12, 2016 at 13:06

4 Answers 4

13

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?

Sign up to request clarification or add additional context in comments.

Comments

13

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).

Comments

8

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.

2 Comments

Perhaps if it was a table that was trying to be dropped, but this is a stored procedure.
This is what I've always used as well.
0

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;

1 Comment

how does this relate to OPs question??

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.