2011-06-10 27 views
8

我需要一些幫助,簡單的SQL代碼:創建過程內部IF部分

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存在
- IF不存在,它會創建它

我的問題是這樣的錯誤信息:

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的身體,簡單的查詢工作
- 當我執行整個IF部分包括'CREATE PROCEDURE'正文,引發錯誤

我在想什麼?

回答

19

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,看看proc存在。

+0

嗯..我應該更願意與OBJECT_ID或通過INFORMATION_SCHEMA檢查?我讀過使用INFORMATION_SCHEMA的地方是更好的主意。 – qlf00n 2011-06-10 12:56:54

+0

@dygi:我總是使用OBJECT_ID,但這取決於你。在其他RDBMS中,您可以使用「CREATE OR REPLACE」或「CREATE IF NOT EXISTS」,因此不用擔心「可移植性」 – gbn 2011-06-10 12:58:29

+0

還有一件事。這個修改是否正確和安全:OBJECT_ID(db_name()+ N'.dbo.Table_Exists',N'P') – qlf00n 2011-06-10 13:17:02

3

MSDN

CREATE PROCEDURE語句不能在單一批次其它Transact-SQL語句組合使用。

因此,你所要做的是不可能的,除非你通過動態查詢來實現它。

14

您可以使用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 
+0

謝謝,它真的有幫助... – ogun 2012-03-27 07:01:36

+0

這很乾淨。我喜歡它。 – 2017-02-28 19:09:08

0
if OBJECT_ID('PROC1') IS NULL 
    EXEC('CREATE PROCEDURE DBO.PROC1 AS SELECT 1') 

GO 

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

AS 

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