0

Consider the following bit of 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

There is then a very long script setting up tables, views, stored procedures etc etc.

I would like to know if SQL would allow something along the likes of the following pseudo code;

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

I am aware of the Exists function in SQL but I can't seem to find anything that would simply abort the remains of the script straightaway.

This script will end up in an installation routine. In theory it should never be in an installer where the database is already present, however I would prefer not to take chances and prepare properly for a potential mistake. It is also crucial that the script does not throw any error as that will just cause the installer to roll back and install nothing.

I'm hoping that something exists in SQL that will just exit a script cleanly if particular conditions are met. By exit I really do mean exit as opposed to simply breaking out of the condition being currently evaluated.

halfer
  • 19,824
  • 17
  • 99
  • 186
Dom Sinclair
  • 2,458
  • 1
  • 30
  • 47
  • What about [RETURN](https://learn.microsoft.com/en-us/sql/t-sql/language-elements/return-transact-sql?view=sql-server-2017)? – Joakim Danielson Aug 01 '18 at 09:34
  • @JoakimDanielson - the problem is, they're thinking of their *script* as the unit they want to exit out of. Being heavily DDL based, it's going to be filled with *multiple* batches, which are the unit at which `RETURN` operates outside of stored procs. – Damien_The_Unbeliever Aug 01 '18 at 09:38

3 Answers3

0

You can use GOTO as follows :

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;
Anupam Singh
  • 1,158
  • 13
  • 25
  • `GOTO` only works within a batch, and since many DDL statements have to be in their own batches, realistically the chances of being able to `GOTO` then end of *this type of script* are low. – Damien_The_Unbeliever Aug 01 '18 at 09:36
0

There are several methods for that kind of request :

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

OR

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

They should work and close the connection.

See here : Answer

Cesar
  • 453
  • 9
  • 21
0

The problem is, your client tool (SSMS, SQLCMd, etc) splits your script into batches based on the location of the GO keyword (it's a client tool thing, not SQL Server at all).

It then sends the first batch. After the first batch is complete (no matter what the outcome), it sends the second batch, then the third after the second, etc.

If you're running with sufficient permissions, a high-valued RAISERROR (severity 20-25) should stop the client tool in its tracks (because it forces the connection closed). It's not that clean though.

Another option is to try to set NOEXEC ON which still does some work with each subsequent batch (compilation) but won't run any of the code1. This allows you a slightly better recovery option if you want some batches at the end to always run, by turning it OFF again.


1Which means you still will see error messages for compilation errors for later batches which rely upon database structures that would have been created in earlier batches, if they weren't being skipped.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
  • Unfortunately I had rather come to much the same conclusion, but thought I'd ask just in case I'd actually overlooked something. I think the answer (at least in my case for the time being) maybe to create two separate installers. One purely for the database engine and database, and a separate one for the actual program that will then use the database. As things stand anyone trying to run repair from the installer will hit this problem. Thank you for your thoughts. – Dom Sinclair Aug 01 '18 at 09:45