T-SQL:停止处理查询的其余部分
Posted
技术标签:
【中文标题】T-SQL:停止处理查询的其余部分【英文标题】:T-SQL: Stop processing rest of the query 【发布时间】:2010-09-14 09:10:17 【问题描述】:我想知道是否可以在特定条件下停止处理其余查询。
场景
IF NOT EXISTS (SELECT *
FROM
[dbo].[Updates]
WHERE
RevisionNumber='12.2457.2')
BEGIN
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[TestProcedure]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN
PRINT 'Test';
END
GO
INSERT [dbo].[Updates]
SELECT '12.2457.2'
END
上述查询将不起作用,因为“GO”后面的行被视为新查询。我们每天都会发布更新,并希望能够简化安装更新。
我正在寻找类似“RETURN”的语句。它有效,但不适用于“GO”。
IF EXISTS (SELECT *
FROM
[dbo].[Updates]
WHERE
RevisionNumber='12.2457.2')
BEGIN
PRINT 'The update ''12.2457.2'' was already installed.'
RETURN
END
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[TestProcedure]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN
PRINT 'Test';
END
GO
INSERT [dbo].[Updates]
SELECT '12.2457.2'
GO
解决方法
BEGIN TRANSACTION
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[TestProcedure]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN
PRINT 'Test';
END
GO
IF EXISTS(SELECT TOP 1 1 FROM [dbo].[Updates] WHERE RevisionNumber='12.2457.2')
BEGIN
ROLLBACK TRANSACTION
PRINT 'The update was already present in the database. The transaction was rolled back.'
END
ELSE
BEGIN
INSERT [dbo].[Updates]
SELECT '12.2457.2'
COMMIT TRANSACTION
PRINT 'The update was sucessfully installed.'
END
我想要的是停止执行其余行的想法,相当于 Visual Basic 中的“RETURN/END”关键字。请帮忙!
【问题讨论】:
【参考方案1】:对于单个语句:
INSERT [dbo].[Updates]
(RevisionNumber,...)
SELECT
'12.2457.2', ...
WHERE
NOT EXISTS (SELECT *
FROM
[dbo].[Updates]
WHERE
RevisionNumber='12.2457.2')
对于多个语句:
IF NOT EXISTS (SELECT *
FROM
[dbo].[Updates]
WHERE
RevisionNumber='12.2457.2')
BEGIN
--do stuff
END
否则,存储过程和返回。
你想做什么?如果要停止重复条目,请查看以下答案:
SQL Server 2008: INSERT if not exits, maintain unique column【讨论】:
我想我并没有像我应该的那样清楚。好吧,让我们从头开始。 1.检查更新表。如果在表上找到更新信息,则不要运行查询的其余部分。 2. 运行 T-SQL 更新。 3.在更新表中插入更新信息。 @Nick Binnet:我认为您关注的是代码流,而不是您想要实际做的事情。是否像“只有在不存在时才插入”一样简单?【参考方案2】:您必须有条件地使用假设的关键字才能使其具有任何值,此时您可以围绕条件重构您的代码 - 也就是说,您没有任何情况需要 em> 一个假设的 STOP 关键字。
在您的情况下,一个简单的NOT EXISTS
或ELSE
就可以了。
【讨论】:
【参考方案3】:终于有办法了。似乎比解决方法更好。
设置 noexec 关闭/打开就可以了。
IF EXISTS (SELECT *
FROM
[dbo].[Updates]
WHERE
RevisionNumber='12.2457.2')
BEGIN
PRINT 'The update ''12.2457.2'' was already installed.'
set noexec on
END
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[TestProcedure]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[TestProcedure]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [dbo].[TestProcedure]
AS
BEGIN
PRINT 'Test';
END
GO
INSERT [dbo].[Updates]
SELECT '12.2457.2'
GO
set noexec off
【讨论】:
以上是关于T-SQL:停止处理查询的其余部分的主要内容,如果未能解决你的问题,请参考以下文章
将 MS Access 查询(使用 IIF() 和 DATESERIAL())事务处理到 T-SQL