如果表尚不存在,我试图运行一些SQL查询,具体来说:
步骤1和2工作正常,但是当我尝试执行第三部分时,我收到错误。这是我的代码(不需要仔细阅读 - 这里作为参考,跳到下面的问题区域):
USE [MyDB]
GO
IF NOT EXISTS (SELECT * FROM sysobjects WHERE name='fooTable' and xtype='U')
BEGIN
CREATE TABLE fooTable
(
ID INT NOT NULL IDENTITY(1,1),
SomeNumber INT NOT NULL,
SomeOtherTable_ID INT NOT NULL,
PRIMARY KEY (ID),
FOREIGN KEY (SomeOtherTable_ID) REFERENCES SomeOtherTable(SomeOtherTable_ID)
);
INSERT INTO fooTable (SomeNumber, SomeOtherTable_ID)
VALUES (5, 1), (10, 1), (25, 1), (50, 1), (100, 1), (500, 1)
CREATE PROCEDURE myProcedureName
AS
SELECT SomeNumber from [fooTable]
END
相关的故障线是第三个,它在if语句的外部工作正常:
CREATE PROCEDURE myProcedureName
AS
SELECT SomeNumber from [fooTable]
但如果我尝试在if块中运行它,SELECT
会用以下内容加下划线红色:
SELECT附近的语法不正确。期待外在。
如何在if块中运行存储过程?如果它是相关的,这是在使用T-SQL的SQL Server中。
答案 0 :(得分:5)
存储过程,触发器,函数和其他几种对象类型需要在它们自己的批处理中。通过将IF
语句包装在CREATE
中,可以在EXEC(N'....')
块内实现此目的:
IF (OBJECT_ID(N'dbo.footTable') IS NULL)
BEGIN
CREATE TABLE dbo.[fooTable]
(
ID INT NOT NULL IDENTITY(1, 1)
CONSTRAINT [PK_fooTable] PRIMARY KEY,
SomeNumber INT NOT NULL,
SomeOtherTable_ID INT NOT NULL
CONSTRAINT [FK_fooTable_SomeOtherTable] FOREIGN KEY
REFERENCES dbo.SomeOtherTable(SomeOtherTable_ID)
);
INSERT INTO dbo.fooTable (SomeNumber, SomeOtherTable_ID)
VALUES (5, 1), (10, 1), (25, 1), (50, 1), (100, 1), (500, 1);
EXEC(N'
CREATE PROCEDURE dbo.myProcedureName
AS
SELECT SomeNumber FROM [fooTable];
');
END;
注意:
请确保在包含动态SQL的字符串文字中包含大写 - N
前缀(作为最佳做法 - 是的,没有它经常有效,但让它始终有效)。
请勿使用已弃用的兼容性视图,例如sysobjects
。从SQL Server 2005的发布开始,正确的系统目录视图位于sys
模式中。在这种情况下,它将是sys.objects
。
您应该对对象进行架构限定:dbo.fooTable
而不仅仅是fooTable
您应该命名您的约束:PK,FK等
答案 1 :(得分:1)
CREATE PROCEDURE需要在自己的块中。将其移出并执行以下操作:
CREATE TABLE `grid` (
`id` int(10) unsigned NOT NULL,
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`customers_id` int(10) unsigned NOT NULL,
`x` int(11) NOT NULL,
`y` int(11) NOT NULL,
`seen` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
答案 2 :(得分:0)
我喜欢以下习语:
if object_id('dbo.yourProc') is not null --object exists
set noexec on;
go
create procedure dbo.yourProc as
begin
select 'not implemented' as [message]
end
go
set noexec off;
go
alter procedure dbo.yourProc as
begin
«actual definition here»
end
go
我喜欢这个是保留程序中已存在的任何权限并且是幂等的。