Sql server 在IF部分内创建过程
我需要一些关于简单SQL代码的帮助:Sql server 在IF部分内创建过程,sql-server,tsql,Sql Server,Tsql,我需要一些关于简单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
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_是否存在
-如果不存在,则创建它 我的问题是此错误信息:
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”body时,它会工作
-当我执行不包括“创建过程”主体的整个IF部分时,简单查询工作
-当我执行包含“创建过程”主体的整个IF节时,抛出错误 我错过了什么?来自: CREATE PROCEDURE语句不能在单个批处理中与其他Transact-SQL语句组合
因此,除非您能够通过动态查询来实现它,否则您试图做的是不可能的。创建过程必须在它自己的批处理中 因此,动态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
还是先放下
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查看进程是否存在。您可以使用
将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
嗯。。我应该选择使用对象ID检查还是通过信息模式检查?我在某个地方读到过,使用信息模式更好。@dygi:我总是使用对象ID,但这取决于你。在其他RDBMS中,您可以使用
CREATE或REPLACE
,或者CREATE(如果不存在的话)
,所以不要再担心“可移植性”了。此修改是否正确且安全:OBJECT_ID(db_name()+N'.dbo.Table_Exists',N'P')@dygi:yes,但您不能使用CREATE PROC db_name()+'.dbo.Table_Exists
,因此您必须已经处于正确的数据库上下文中。您不能在动态SQL中使用CREATE PROC…明白。非常感谢。这是干净的。我喜欢它。
if OBJECT_ID('PROC1') IS NULL
EXEC('CREATE PROCEDURE DBO.PROC1 AS SELECT 1')
GO
ALTER PROCEDURE DBO.PROC1(@PARAM1 INT, @PARAM2 INT)
AS