Can someone tell me when and where I need to use begin and end blocks in SQL Server?
Also, what exactly does the Go keyword do?
After wrestling with this problem today my opinion is this: BEGIN...END brackets code just like {....} does in C languages, e.g. code blocks for if...else and loops
GO is (must be) used when succeeding statements rely on an object defined by a previous statement. USE database is a good example above, but the following will also bite you:
alter table foo add bar varchar(8);
-- if you don't put GO here then the following line will error as it doesn't know what bar is.
update foo set bar = 'bacon';
-- need a GO here to tell the interpreter to execute this statement, otherwise the Parser will lump it together with all successive statements.
It seems to me the problem is this: the SQL Server SQL Parser, unlike the Oracle one, is unable to realise that you're defining a new symbol on the first line and that it's ok to reference in the following lines. It doesn't "see" the symbol until it encounters a GO token which tells it to execute the preceding SQL since the last GO, at which point the symbol is applied to the database and becomes visible to the parser.
Why it doesn't just treat the semi-colon as a semantic break and apply statements individually I don't know and wish it would. Only bonus I can see is that you can put a print() statement just before the GO and if any of the statements fail the print won't execute. Lot of trouble for a minor gain though.