What is the difference between ; and GO in T-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
In SQL Server, when should you use GO and when should you use 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.
What is the difference between ; and GO in stored procedure in SQL Server?
;
just ends the statement.
GO is not a statement but a command to the server to commit the current batch to the Database. It creates a stop inside the transaction.
http://msdn.microsoft.com/en-us/library/ms188037.aspx
(Update, thanks for the comments):
GO is a statement intended for the Management studio as far as I know, maybe to other tools as well.
Use of Begin / End Blocks and the Go keyword in SQL Server?
GO is like the end of a script.
You could have multiple CREATE TABLE statements, separated by GO. It's a way of isolating one part of the script from another, but submitting it all in one block.
BEGIN and END are just like { and } in C/++/#, Java, etc.
They bound a logical block of code. I tend to use BEGIN and END at the start and end of a stored procedure, but it's not strictly necessary there. Where it IS necessary is for loops, and IF statements, etc, where you need more then one step...
IF EXISTS (SELECT * FROM my_table WHERE id = @id)
BEGIN
INSERT INTO Log SELECT @id, 'deleted'
DELETE my_table WHERE id = @id
END
What is a batch, and why is GO used?
GO
is not properly a TSQL command.
Instead it's a command to the specific client program which connects to an SQL server (Sybase or Microsoft's - not sure about what Oracle does), signalling to the client program that the set of commands that were input into it up till the "go" need to be sent to the server to be executed.
Why/when do you need it?
GO in MS SQL server has a "count" parameter - so you can use it as a "repeat N times" shortcut.
Extremely large updates might fill up the SQL server's log. To avoid that, they might need to be separated into smaller batches via
go
.In your example, if updating for a set of country codes has such a volume that it will run out of log space, the solution is to separate each country code into a separate transaction - which can be done by separating them on the client with
go
.Some SQL statements MUST be separated by GO from the following ones in order to work.
For example, you can't drop a table and re-create the same-named table in a single transaction, at least in Sybase (ditto for creating procedures/triggers):
> drop table tempdb.guest.x1
> create table tempdb.guest.x1 (a int)
> go
Msg 2714, Level 16, State 1
Server 'SYBDEV', Line 2
There is already an object named 'x1' in the database.
> drop table tempdb.guest.x1
> go
> create table tempdb.guest.x1 (a int)
> go
>
DBeaver SQL Server GO invalid
This should work.
- Open connection editor
- click on "Edit Driver".
- Switch tab on "Adv.
parameters". - Set "Script delimiter" value to "go".
GO batch support
SQL select where not in subquery returns no results
Update:
These articles in my blog describe the differences between the methods in more detail:
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:SQL Server
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:PostgreSQL
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:Oracle
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:MySQL
There are three ways to do such a query:
LEFT JOIN / IS NULL
:SELECT *
FROM common
LEFT JOIN
table1 t1
ON t1.common_id = common.common_id
WHERE t1.common_id IS NULLNOT EXISTS
:SELECT *
FROM common
WHERE NOT EXISTS
(
SELECT NULL
FROM table1 t1
WHERE t1.common_id = common.common_id
)NOT IN
:SELECT *
FROM common
WHERE common_id NOT IN
(
SELECT common_id
FROM table1 t1
)
When table1.common_id
is not nullable, all these queries are semantically the same.
When it is nullable, NOT IN
is different, since IN
(and, therefore, NOT IN
) return NULL
when a value does not match anything in a list containing a NULL
.
This may be confusing but may become more obvious if we recall the alternate syntax for this:
common_id = ANY
(
SELECT common_id
FROM table1 t1
)
The result of this condition is a boolean product of all comparisons within the list. Of course, a single NULL
value yields the NULL
result which renders the whole result NULL
too.
We never cannot say definitely that common_id
is not equal to anything from this list, since at least one of the values is NULL
.
Suppose we have these data:
common
--
1
3
table1
--
NULL
1
2
LEFT JOIN / IS NULL
and NOT EXISTS
will return 3
, NOT IN
will return nothing (since it will always evaluate to either FALSE
or NULL
).
In MySQL
, in case on non-nullable column, LEFT JOIN / IS NULL
and NOT IN
are a little bit (several percent) more efficient than NOT EXISTS
. If the column is nullable, NOT EXISTS
is the most efficient (again, not much).
In Oracle
, all three queries yield same plans (an ANTI JOIN
).
In SQL Server
, NOT IN
/ NOT EXISTS
are more efficient, since LEFT JOIN / IS NULL
cannot be optimized to an ANTI JOIN
by its optimizer.
In PostgreSQL
, LEFT JOIN / IS NULL
and NOT EXISTS
are more efficient than NOT IN
, sine they are optimized to an Anti Join
, while NOT IN
uses hashed subplan
(or even a plain subplan
if the subquery is too large to hash)
Related Topics
How to Find the Last Modified Date, Modified User of an Stored Procedure in SQL Server 2008
Querying Where Condition to Character Length
How to Use Merge on Linked Servers
SQL Update If Parameter Is Not Null or Empty
Select Count of Rows in Another Table in a Postgres Select Statement
SQL Server: How to Check If Clr Is Enabled
Activerecord: List Columns in Table from Console
Type to Use for "Status" Columns in a SQL Table
How to Take Last Four Characters from a Varchar
Pivot a Table on a Value But Group the Data on One Line by Another
Insert Multiple Values Using Insert into (SQL Server 2005)
Select Latest Records by Datetime Field
How to Grab a Value of a Column That Is Set as a String
Selecting Distinct Combinations
How to Get Second-Highest Salary Employees in a Table
Copy from One Database to Another Using Oracle SQL Developer - Connection Failed