Удалить и повторно создать процедуру, если она существует в T-SQL не работает

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

У меня есть приведенный выше код, чтобы проверить, существует ли местоположение хранимой процедуры в текущей базе данных. Я ожидаю, что он упадет и воссоздаст процедуру, если она существует.

однако, если процедура существует, код все еще выполняется, и в результате я получаю следующую ошибку: "в базе данных уже есть объект с именем "LOCATION".'

почему этот код не может удалить процедуру, если она существует?

тот же код работает правильно для другого процедура в той же базе данных.

3 ответов


попробуйте это (предпочтительный метод с помощью представления):

IF EXISTS(SELECT 1
          FROM   INFORMATION_SCHEMA.ROUTINES
          WHERE  ROUTINE_NAME = 'PRC_NAME'
                 AND SPECIFIC_SCHEMA = 'schema_name')
  BEGIN
      DROP PROCEDURE PRC_NAME
  END

или (не рекомендуется использовать прямой доступ к системной таблице):

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

почему предпочтителен первый метод, вы можете узнать, например, в этом вопросе:SQL Server: должен ли я использовать таблицы information_schema над таблицами sys?


это немного поздно, но другие, которые в конечном итоге здесь, могут захотеть проверить документация MSDN которые говорят, что вы можете использовать:

DROP PROCEDURE IF EXISTS dbo.uspMyProc;
GO

это, однако, доступно из SQL Server 2016 Community Technology Preview 3.3 (CTP 3.3).


вы можете использовать:

IF OBJECT_ID('MSL_GET_IP_LOCATION', 'P') IS NOT NULL
  DROP PROCEDURE MSL_GET_IP_LOCATION
GO

дальнейшая мысль об этом-вам нужно будет убедиться, что у вас есть уникальные имена для всех объектов.