Introduction to T-SQL
Learn what sets T-SQL apart from standard SQL: variables, control-of-flow, error handling, statement structure, and batches with GO.
Introduction
So far you've run simple SELECT statements and DDL commands like CREATE DATABASE. Those are standard SQL — portable across most relational databases with minor syntax differences. This lesson introduces the parts of T-SQL that are not standard SQL at all: variables, branching logic, loops, and structured error handling. These are the features that let T-SQL function as a real programming language, not just a query language.
What Makes T-SQL Different
Standard SQL (the ANSI/ISO standard) defines how to describe and manipulate data: SELECT, INSERT, UPDATE, DELETE, CREATE TABLE, and so on. It does not define variables, loops, or conditional branching in a single script — that logic traditionally lived in the application layer. T-SQL adds a procedural layer directly on top of standard SQL, letting you write scripts and stored procedures with real logic that runs inside the database engine itself, close to the data it operates on.
| Feature | Standard SQL | T-SQL |
|---|---|---|
| Query data | Yes (SELECT) | Yes (SELECT) |
| Variables | Not standard | DECLARE / SET / SELECT |
| Conditionals | Not standard | IF / ELSE |
| Loops | Not standard | WHILE |
| Error handling | Not standard | TRY / CATCH |
| Reusable routines | Varies by vendor | Stored procedures, functions |
Variables
T-SQL variables always start with an @ symbol and must be declared with a data type before use, using DECLARE. You can assign values with SET (for a single value) or SELECT (which can pull a value straight from a query).
DECLARE @studentName NVARCHAR(50);DECLARE @minMarks INT = 60;
SET @studentName = 'Ananya Rao';
SELECT @studentName AS StudentName, @minMarks AS PassingMark;Click Run to see what this code prints.
Control-of-Flow
IF/ELSE lets you branch based on a condition, and WHILE lets you repeat a block of statements. T-SQL uses BEGIN and END to group multiple statements into a single block, similar to curly braces in other languages.
DECLARE @counter INT = 1;
WHILE @counter <= 3BEGIN PRINT 'Iteration number: ' + CAST(@counter AS VARCHAR(10)); SET @counter = @counter + 1;END;
IF @counter > 3 PRINT 'Loop finished.';ELSE PRINT 'Loop still running.';Click Run to see what this code prints.
Error Handling
TRY/CATCH lets you handle errors gracefully instead of letting a script fail with a raw error message. Statements that might fail go in the TRY block; if any of them raises an error, control jumps immediately to the CATCH block.
BEGIN TRY SELECT 10 / 0 AS Result;END TRYBEGIN CATCH PRINT 'An error occurred: ' + ERROR_MESSAGE();END CATCH;Click Run to see what this code prints.
Batches and GO
GO is not a T-SQL statement at all — it's a client-side batch separator recognized by SSMS and other tools. It tells the client 'send everything above this point to the server as one unit, then start a new batch.' Some statements, like CREATE PROCEDURE, must be the first statement in their batch, which is why you'll often see GO immediately before them.
USE SchoolDB;GO
DECLARE @today DATE = GETDATE();PRINT 'Today is: ' + CAST(@today AS VARCHAR(20));GO
-- A new batch starts here; @today from above no longer exists.PRINT 'This is a fresh batch.';Because GO starts a brand-new batch, any variable declared with DECLARE before a GO is gone afterward. If you reference it below a GO, SQL Server will raise a 'Must declare the scalar variable' error.
Statement Structure
T-SQL statements traditionally end with a semicolon. Older T-SQL code often omits semicolons and still runs, because SQL Server has historically been lenient about it — but Microsoft has stated semicolons will become mandatory in a future version, and some newer statements (like those using common table expressions) already require them. This course terminates every statement with a semicolon, which is the modern, safe habit to build.
Common Mistakes
- Forgetting the @ prefix on variable names — T-SQL requires it, unlike some other procedural SQL dialects.
- Referencing a variable declared before a GO in a batch after that GO — it will no longer exist.
- Mixing SET and SELECT for assignment without understanding the difference: SELECT can assign from a query result, while SET is limited to a single expression.
- Wrapping only the statement that might fail in TRY, but forgetting that any statement after it in the same TRY block still executes if no error occurred yet.
Best Practices
- End every statement with a semicolon, even though older T-SQL tolerates omitting it.
- Use BEGIN/END around every IF, ELSE, and WHILE body once it contains more than one statement, to avoid ambiguity.
- Wrap risky operations (data conversions, division, external calls) in TRY/CATCH rather than letting scripts fail with a raw system error.
- Treat GO as a batch boundary, not just a formatting habit — remember variables and local temp state don't survive across it.
Frequently Asked Questions
No. GO is a batch separator recognized by client tools like SSMS and sqlcmd, not part of the T-SQL language itself. SQL Server's engine never sees the word GO.
SET assigns exactly one variable from a single expression and is the ANSI-standard-friendly choice. SELECT can assign a variable directly from a column in a query, and can technically assign multiple variables in one statement, but silently does nothing if the query returns zero rows — SET would still succeed with NULL in that case.
No, not for simple, safe SELECT statements. It becomes important for INSERT/UPDATE/DELETE operations, calculations that might divide by zero or overflow, and any script where you want controlled error reporting instead of a raw failure.
Yes. IF, WHILE, TRY/CATCH, and BEGIN/END can all be nested, just like in general-purpose programming languages.
Key Takeaways
- T-SQL extends standard SQL with variables, control-of-flow, and structured error handling.
- Variables are declared with DECLARE @name TYPE and always start with @.
- IF/ELSE and WHILE provide branching and looping; BEGIN/END group multi-statement blocks.
- TRY/CATCH lets you handle errors gracefully instead of letting a script crash.
- GO is a client-side batch separator, not a T-SQL statement — variables don't survive across it.
Summary
You've now seen the procedural features that set T-SQL apart from plain SQL. With that foundation, the next lesson turns to the building blocks of every table you'll create: SQL Server's data types.