Создание процедуры в разделе IF - PullRequest
9 голосов
/ 10 июня 2011

Мне нужна помощь с простым кодом SQL:

DECLARE @procExists int
SET @procExists = (SELECT COUNT(*) FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA = 'dbo' AND ROUTINE_NAME = 'Table_Exists' AND ROUTINE_TYPE = 'PROCEDURE')
IF NOT @procExists > 0 
BEGIN
    -- test query
    -- SELECT 'Something' = @procExists;

    -- error throwing code
    -- CREATE PROCEDURE Table_Exists
    --     @schemaName varchar(50),
    --     @tableName varchar(50)
    -- AS
    --     RETURN (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @schemaName AND TABLE_NAME = @tableName)
END

Простой код выше:
- объявляет переменную типа int
- проверяет, существует ли процедура dbo.Table_Exists
- Если не существует, он создает его

Моя проблема - это информация об ошибке:

Msg 156, Level 15, State 1, Line 9
Incorrect syntax near the keyword 'PROCEDURE'.
Msg 137, Level 15, State 2, Line 13
Must declare the scalar variable "@schemaName".

Не знаю почему, но ..
- когда я выполняю 'CREATE PROCEDURE' тело в одиночку оно работает
- когда я выполняю весь раздел IF , исключая тело 'CREATE PROCEDURE', простой запрос работает
- когда я выполняю весь раздел ЕСЛИ , включая тело 'CREATE PROCEDURE', выдается ошибка

Чего мне не хватает?

Ответы [ 4 ]

21 голосов
/ 10 июня 2011

CREATE PROCEDURE должна быть в своем собственном пакете

Итак, динамический SQL - это один из способов:

IF OBJECT_ID('Table_Exists') IS NULL
BEGIN
    EXEC ('CREATE PROCEDURE Table_Exists
         @schemaName varchar(50),
         @tableName varchar(50)
     AS
         RETURN (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @schemaName AND TABLE_NAME = @tableName)
')
END

или сначала DROP

IF OBJECT_ID('Table_Exists') IS NOT NULL
  DROP PROC Table_Exists
GO
CREATE PROCEDURE Table_Exists
         @schemaName varchar(50),
         @tableName varchar(50)
     AS
         RETURN (SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = @schemaName AND TABLE_NAME = @tableName)
GO

Обратите внимание на использованиеOBJECT_ID, чтобы проверить, существует ли процедура.

15 голосов
/ 10 июня 2011

Вы можете сделать это, используя SET NOEXEC ON.Это указывает SQL Server игнорировать весь код SQL, пока не будет достигнут SET NOEXEC OFF.

IF EXISTS (SELECT *
          FROM INFORMATION_SCHEMA.ROUTINES
          WHERE ROUTINE_TYPE = 'PROCEDURE'
          AND ROUTINE_SCHEMA = 'dbo'
          AND ROUTINE_NAME = 'HelloWorld')
BEGIN
    SET NOEXEC ON
END
GO

CREATE PROCEDURE dbo.HelloWorld
AS
    PRINT 'Hello world'
GO

SET NOEXEC OFF
GO
3 голосов
/ 10 июня 2011

С MSDN :

Оператор CREATE PROCEDURE нельзя объединить с другими операторами Transact-SQL в одном пакете.

Следовательно, то, что вы пытаетесь сделать, невозможно, если вы не справляетесь с реализацией этого посредством динамического запроса.

0 голосов
/ 28 октября 2016
if OBJECT_ID('PROC1') IS NULL  
   EXEC('CREATE PROCEDURE DBO.PROC1 AS SELECT 1')

GO

ALTER PROCEDURE DBO.PROC1(@PARAM1 INT, @PARAM2 INT)

AS

.................

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...