0

考虑以下 SQL

    SET DATEFORMAT ymd
SET ARITHABORT, ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, QUOTED_IDENTIFIER, ANSI_NULLS, NOCOUNT ON
SET NUMERIC_ROUNDABORT, IMPLICIT_TRANSACTIONS, XACT_ABORT OFF
GO
USE master
GO

IF DB_NAME() <> N'master' SET NOEXEC ON

--
-- Create database [myDatabaseName]
--
PRINT (N'Create database [myDatabaseName]')
GO
CREATE DATABASE myDatabaseName

然后有一个很长的脚本来设置表、视图、存储过程等。

我想知道 SQL 是否允许以下​​伪代码之类的东西;

If (myDatabaseName Exists)
     Return  // in other word abort the script here but don't throw an error
Else
 //Carry on and install the database

我知道 SQL 中的 Exists 函数,但我似乎找不到任何可以直接中止脚本剩余部分的东西。

该脚本将在安装例程中结束。从理论上讲,它永远不应该在数据库已经存在的安装程序中,但是我不希望冒险并为潜在的错误做好适当的准备。脚本不会抛出任何错误也很重要,因为这只会导致安装程序回滚并且什么都不安装。

我希望 SQL 中存在一些东西,如果满足特定条件,它就会干净地退出脚本。退出我的意思是退出,而不是简单地打破当前正在评估的条件。

4

3 回答 3

0

您可以按如下方式使用 GOTO:

If (myDatabaseName Exists)
     GOTO QUIT;  // in other word abort the script here but don't throw an error
Else
 //Carry on and install the database

QUIT:
  SELECT 0;
于 2018-08-01T09:34:15.733 回答
0

这种请求有几种方法:

raiserror('Oh no a fatal error', 20, -1) with log

或者

print 'Fatal error, script will not continue!'
set noexec on

他们应该工作并关闭连接。

看这里:答案

于 2018-08-01T09:35:39.867 回答
0

问题是,您的客户端工具(SSMS、SQLCMd 等)根据关键字的位置将您的脚本分成多个批次GO(它是客户端工具,根本不是 SQL Server)。

然后它发送第一批。第一批完成后(无论结果如何),它会发送第二批,然后在第二批之后发送第三批,依此类推。

如果您以足够的权限运行,则高值RAISERROR(严重性 20-25)应停止客户端工具的运行(因为它会强制关闭连接)。虽然不是那么干净。

另一种选择是尝试设置NOEXEC ONwhich 仍然对每个后续批次(编译)进行一些工作,但不会运行任何代码1。如果您希望最后的某些批次始终运行,则可以通过OFF再次转动它来获得更好的恢复选项。


1这意味着您仍然会看到后续批次的编译错误的错误消息,这些错误消息依赖于在早期批次中创建的数据库结构,如果它们没有被跳过的话。

于 2018-08-01T09:35:49.747 回答