2011-06-10 16 views
8

Necesito un poco de ayuda con el código SQL simple:procedimiento de creación dentro de la sección SI

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 

El código anterior simple:
- declara una variable int
- comprueba si dbo.Table_Exists procedimiento existe
- SI NO existe lo crea

Mi problema es el siguiente información de error:

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

no sé por qué, pero ..
- cuando yo haga 'Crear PROCEDIMIENTO' cuerpo sola funciona
- cuando yo haga toda la sección SI excluyendo 'CREATE PROCEDURE' cuerpo, simple consulta funciona
- cuando ejecuto la sección IF completa incluyendo 'CREAR PROCEDIMIENTO' cuerpo, se produce un error

¿Qué me falta?

Respuesta

19

CREAR procedimiento tiene que estar en su propio lote

Por lo tanto, SQL dinámico es una manera:

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 

o DROP primera

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 

Nota el uso de OBJECT_ID para ver si el proceso existe

+0

Hmm .. ¿Debo prefieren consultar con OBJECT_ID oa través de INFORMATION_SCHEMA? He leído en alguna parte que usar INFORMATION_SCHEMA es una mejor idea. – qlf00n

+0

@dygi: siempre uso OBJECT_ID pero depende de usted. En otro RDBMS usaría 'CREATE or REPLACE', o' CREATE IF NOT EXISTS' de todos modos, así que no se preocupe por la "portabilidad" – gbn

+0

Una cosa más. ¿Es correcta y segura esta modificación? OBJECT_ID (db_name() + N'.dbo.Table_Exists ', N'P') – qlf00n

3

De MSDN:

La sentencia CREATE PROCEDURE no se puede combinar con otras instrucciones Transact-SQL en un solo lote.

Por lo tanto, lo que está tratando de hacer no es posible, a menos que esté bien implementarlo mediante una consulta dinámica.

14

Puede hacerlo usando SET NOEXEC ON. Esto indica a SQL Server que ignore todo el código SQL hasta que se llegue al 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

gracias, realmente ayuda ... – ogun

+0

Esto está limpio. Lo amo. –

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 

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

Cuestiones relacionadas