What is the difference between ";" and "GO" in T-SQL? - sql

I use ADO.NET as well as the sqlcmd utility to send SQL scripts to SQL Server 2008. What is the difference between using ; and GO to separate chunks of SQL?

GO is not actually a T-SQL command. The GO command was introduced by Microsoft tools as a way to separate batch statements such as the end of a stored procedure. GO is supported by the Microsoft SQL stack tools but is not formally part of other tools.
You cannot put a GO into a string of SQL and send it as part of a ADO.NET command object as SQL itself does not understand the term. Another way to demonstrate this is with the profiler: set up some statements that use GO in Query Analyzer/Management Studio and then run the profiler when you execute. You will see they are issued as separate commands to the server.
The semi-colon is used to signify the end of a statement itself, not necessarily a whole batch.
http://msdn.microsoft.com/en-us/library/ms188037.aspx

"GO" is similar to ; in many cases, but does in fact signify the end of a batch.
Each batch is committed when the "GO" statement is called, so if you have:
SELECT * FROM table-that-does-not-exist;
SELECT * FROM good-table;
in your batch, then the good-table select will never get called because the first select will cause an error.
If you instead had:
SELECT * FROM table-that-does-not-exist
GO
SELECT * FROM good-table
GO
The first select statement still causes an error, but since the second statement is in its own batch, it will still execute.
GO has nothing to do with committing a transaction.

semicolon is a statement separator. The previous statement(s) is not necessarily executed when a semicolon is encountered.
GO
Signifies the end of a batch. Executes the previous batch of statements, as does encountering the end of the block.
GO 2
Means execute the batch that many times. I think I've used that option maybe twice in my life. Then again, I'm not a DBA by trade.

Under SQL Server TSQL (2005 - 2016) bear in mind that:
Semicolon (;) is a block terminator.
GO is a batch terminator.
Additionally, GO can be used to invoke the same DML block multiple times using the following syntax:
GO [count]
Where [count] is a positive integer that indicates how many times the TSQL block of commands preceding said GO are to be carried out over and over.
Also, unlike semicolon, GO is mandatory before a new DDL, say, when you create a new view, since a semicolon separating previous commands will trigger an error. For example:
drop view #temporary_viewGO
create view #another_view...
--> NO ERRORS
If you replaced GO with a semicolon in the previous example, it will raise the following error message:
'CREATE VIEW' must be the first statement in a query batch.

'GO' is typically used to indicate the end of a batch of SQL statements which means that you could have a begin transaction and end transaction wrapped up into a single collection of statements that could fail or succeed together.
';' is generally used to separate multiple SQL statements from one another. This is noticable in SQL scripts that need to return multiple recordsets, such as `select * from table1; select * from table2;' which would result in two separate recordsets on the client's side.

The command GO means the end of a batch.
Therefore all variables declared before GO are invalid after the GO command.
Against the semicolon does not end the batch.
If You will use a DML command in a procedure, use the semicolon instead GO.
For example:
CREATE PROCEDURE SpMyProc
#myProcParam VARCHAR(20)
AS
DECLARE #myOtherParam INT = 5
;DISABLE TRIGGER ALL ON tMyTable
UPDATE tMyTable SET myVar = #myProcParam, mySecondVar = #myOtherParam
;ENABLE TRIGGER OLL ON tMyTable

I thought the ; character separates a list of SQL commands, GO just instructs SQL Server to commit all the previous commands.

Related

The real function of the "GO" Statement in SQL?

I heard that GO statement separates the command batches in SQL. And the CREATE transaction should be the only query on a batch.
But when i try:
Create database dbTest
Create table tbSomething(ID int primary key,Name varchar(30))
GO
The output is still SUCCESS.
So how does the GO Statement affect the SQL batches?
GO is used to divide a script into multiple batches.
The word GO is not a sql statement. It is understood by the SQL batch processor (for example SSMS) not by SQL Server.
Simply put, if GO appears on a line on its own, SSMS sends each section delimited by GO as a separate batch. SQL Server never sees the GO lines, only the SQL between them.
Because SQL Server has a syntactic rule that stored procedures must be defined in a batch on their own, you will often find database creation scripts which use GO to delimit the batches so that multiple stored procedures can be created from one script. However it is the client software which understands GO and divides the batches, not SQL server.
'GO' statement in SQL server is to just sends a signal to take the current batch of SQL statements for execution.
To tell in simple words, it works like a delimiter.
It is an indication of end of SQL statement [i.e., 1 batch that needs to be executed].

Can the use or lack of use of "GO" in T-SQL scripts effect the outcome?

We have an SSIS package that ran in production on a SQL 2008 box with a 2005 compatibility setting. The package contains a SQL Task and it appears as though the SQL at the end of the script did not run.
The person who worked on that package noted before leaving the company that the package needed "GOs" between the individual SQL commands to correct the issue. however, when testing in development on SQL Server 2008 with 2008 compatibility, the package worked fine.
From what I know, GO's place commands in batches, where commands are sent to the database provider in a batch, for efficiency's sake. I am thinking that the only way that GO should effect the outcome is if there was an error in that script somewhere above it. I can imagine GO in that case, and only that case, effecting the outcome. However, we have seen no evidence of any errors logged.
Can someone suggest to me whether or not GO is even likely related to the problem? Assuming no error was encountered, my understanding of the "GO" command suggests that it use or lack of use is most likely unrelated to the problem.
The GO keyword is, as you say, a batch separator that is used by the SQL Server management tools. It's important to note, though, that the keyword itself is parsed by the client, not the server.
Depending on the version of SQL Server in question, some things do need to be placed into distinct batches, such as creating and using a database. There are also some operations that must take place at the beginning of a batch (like the use statement), so using these keywords means that you'll have to break the script up into batches.
A couple of things to keep in mind about breaking a script up into multiple batches:
When an error is encountered within a batch, execution of that batch stops. However, if your script has multiple batches, an error in one batch will only stop that batch from executing; subsequent batches will still execute
Variables declared within a batch are available to that batch only; they cannot be used in other batches
If the script is performing nothing but CRUD operations, then there's no need to break it up into multiple batches unless any of the above behavioral differences is desired.
All of your assumptions are correct.
One thing that I've experienced is that if you have a batch of statements that is a pre-requisite for another batch, you may need to separate them with a GO. One example may be if you add a column to a table and then update that column (I think...). But if it's just a series of DML queries, then the absence or presence of GO shouldn't matter.
I've noticed that if you set up any variables in the script their state (and maybe the variables themselves) are wiped after a 'GO' statement so they can't be reused. This was certainly the case on SQL Server 2000 and I presume it will be the case on 2005 and 2008 as well.
Yes, GO can affect outcome.
GO between statements will allow execution to continue if there is an error in between. For example, compare the output of these two scripts:
SELECT * FROM table_does_not_exist;
SELECT * FROM sys.objects;
...
SELECT * FROM table_does_not_exist;
GO
SELECT * FROM sys.objects;
As others identified, you may need to issue GO if you need changes applied before you work on them (e.g. a new column) but you can't persist local or table variables across GO...
Finally, note that GO is not a T-SQL keyword, it is a batch separator. This is why you can't put GO in the middle of a stored procedure, for example ... SQL Server itself has no idea what GO means.
EDIT however one answer stated that transactions cannot span batches, which I disagree with:
CREATE TABLE #foo(id INT);
GO
BEGIN TRANSACTION;
GO
INSERT #foo(id) SELECT 1;
GO
SELECT ##TRANCOUNT; -- 1
GO
COMMIT TRANSACTION;
GO
DROP TABLE #foo;
GO
SELECT ##TRANCOUNT; -- 0

Do I have to write the "GO" word in order to execute an SQL server statement?

I have little to no experience with TSQL and SQL Server - so in MySQL when I want to execute a statement I simply write:
Select * from users
...and then hit ENTER.
However now I see many SQL Server tutorials that you have the GO word immediately after each statement. Do I have to write this? For example:
Select * from users; GO
Or I can simply write:
Select * from users; <enter key pressed...>
In SQL Server, go separates query batches. It's optional in most situations.
In earlier versions of SQL Server, you had to do a go after altering a table, like:
alter table MyTable add MyColumn int
go
select MyColumn from MyTable
If you didn't, SQL Server would parse the query batch, and complain that MyColumn didn't exist. See MSDN:
SQL Server utilities interpret GO as a
signal that they should send the
current batch of Transact-SQL
statements to an instance of SQL
Server. The current batch of
statements is composed of all
statements entered since the last GO,
or since the start of the ad hoc
session or script if this is the first
GO.
GO separates batches, as Andomar wrote.
Some SQL statements (e.g. CREATE SCHEMA) need to be the first or only statements within a batch. For example, MSDN states
The CREATE PROCEDURE statement cannot
be combined with other Transact-SQL
statements in a single batch.
Local variables are also limited to a batch, and therefore are not accessible after a GO.
Go is optional, no need to write that in your sql statements.
You don't have to. What the GO will do is execute each statement (at least in Sql Server)
As the other answerers said before me, you don't really NEED Go.
There is only one case when you have to use it, and that's when you want to create a table or view and then select from it.
For example:
create view MyView as select * from MyTable
go
select * from MyView
Without Go, Sql Server won't execute this because the select statement is not valid, because the view doesn't exist at that moment.

Executing a command string with GO at the end

I need to execute a command string with using GO command at the end like
exec('SELECT * FROM tblTmp where Id = 1 GO')
After executing I have
Incorrect syntax near 'GO'.
If I execute exec('SELECT * FROM tblTmp GO') everything is OK
What's the issue here?
Thank you.
GO is not an SQL command, it is a batch separator understood by clients like osql, sqlcmd, and SSMS but not the engine itself.
If you write something like this in SSMS:
SELECT 1
GO
SELECT 2
GO
, the engine sends two batches with one statement in each instead of one batch with two statements.
In your second query, GO is treated as an alias to the table tblTmp.
Just remove GO from your query.
You do not need to use GO for a single SQL statement. Only when you're batching several statements into a single script do you need to use a separator. Also, if you're executing these programmatically you should be using the semicolon (;) statement terminator instead of GO to separate your SQL statement.
Here's a handy SQL Server Central article on the usage of GO and the semicolon.

In SQL Server, when should you use GO and when should you use semi-colon ;?

I’ve always been confused with when I should use the GO keyword after commands and whether a semi-colon is required at the end of commands. What is the differences and why/when I should use them?
When I run the Generate-script in SQL Server Management Studio, it seems to use GO all over the place, but not the semi-colon.
GO only relates to SSMS - it isn't actual Transact SQL, it just tells SSMS to send the SQL statements between each GO in individual batches sequentially.
The ; is a SQL statement delimiter, but for the most part the engine can interpret where your statements are broken up.
The main exception, and place where the ; is used most often is before a Common Table Expression Statement.
The reason why you see so many GO's in Generated DDL scripts is because of the following rule about batches.
CREATE DEFAULT, CREATE FUNCTION,
CREATE PROCEDURE, CREATE RULE, CREATE
TRIGGER, and CREATE VIEW statements
cannot be combined with other
statements in a batch. The CREATE
statement must begin the batch. All
other statements that follow in that
batch will be interpreted as part of
the definition of the first CREATE
statement.
One of the use cases for Generated DDL is to generate multiple objects in a single file. Because of this a DDL generator must be able to generate batches. As others have said the GO statement ends the batch.
GO
Go is a batch separator. This means that everything in that batch is local to that particular batch.
Any declarations of Variables, Table Variables, etc do not go across GO statements.
#Temp tables are local to a connection, so they span across GO statements.
Semicolon
A Semicolon is a statement terminator. This is purely used to identify that a particular statement has ended.
In most cases, the statement syntax itself is enough to determine the end of a statement.
CTE's however, demand that the WITH is the first statement so you need a semicolon before the WITH.
You should use a semi-colon to terminate every SQL statement. This is defined in the SQL Standards,
Sure, more often than not SQL Server allows you to omit the statement terminator but why get into bad habits?
As others have pointed out, the statement preceding a common table expression (CTE) must be terminated with a semi-colon. As a consequence, from folk who have not fully embraced the semi-colon terminator, we see this:
;WITH ...
which I think looks really odd. I suppose it makes sense in an online forum when you can't tell the quality of code it will be pasted into.
Additionally, a MERGE statement must be terminated by a semi-colon. Do you see a pattern here? These are a couple of the newer additions to TSQL which closely follow SQL Standards. Looks like the SQL Server team are going down the road of mandating the use of the semi-colon terminator.
GO is a batch terminator, a semi-colon is a statement terminator.
you will use GO when you want to have multiple create proc statements in 1 script because create proc has to be the first statement in a batch. If you use common table expressions then the statement before it needs to be terminated with a semi-colon