在IF部分内创建程序

Krz*_*ter 9 t-sql sql-server

我需要一些简单的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
Run Code Online (Sandbox Code Playgroud)

上面的简单代码:
- 声明一个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".
Run Code Online (Sandbox Code Playgroud)

我不知道为什么,但是..
- 当我执行'CREATE PROCEDURE' 单独它的工作时
- 当我执行整个IF部分,不包括 'CREATE PROCEDURE'正文,简单查询工作
- 当我执行整个IF部分包括 'CREATE PROCEDURE '身体,错误被抛出

我错过了什么?

gbn*_*gbn 21

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
Run Code Online (Sandbox Code Playgroud)

或首先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
Run Code Online (Sandbox Code Playgroud)

注意使用OBJECT_ID来查看proc是否存在.


Ant*_*ull 16

你可以使用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
Run Code Online (Sandbox Code Playgroud)