What is a cursor in T-SQL, and why should you usually avoid it?
Quick Answer
A cursor processes a result set one row at a time in a loop — the opposite of SQL's set-based nature. It's usually much slower and holds locks/resources longer than an equivalent set-based statement. Avoid it when a single UPDATE/INSERT...SELECT/MERGE can do the job.
A cursor walks a result set row by row in a loop. SQL is designed to work on sets, so a cursor is nearly always slower and holds locks and resources longer than the equivalent single statement. Ninety percent of the time, what someone's doing with a cursor is really an UPDATE ... WHERE or an INSERT ... SELECT. Where a cursor is genuinely reasonable is when you have to call a stored procedure once per row, or you're doing an administrative task iterating over objects, or you need tightly controlled batching of a massive operation.
- Set-based:
UPDATE Orders SET Status = 'Stale' WHERE UpdatedAt < @cutoff;— one statement, one plan. - Cursor version: declare, open, fetch, loop, update per row, close, deallocate — 100× the work for the same result.
- Legit uses: calling a stored procedure per row, iterating over databases/objects for admin tasks, complex running calculations that can't be expressed as a window function, controlled batching of a huge operation.
- If you must loop, a
WHILEloop over a batchedDELETE TOP (n)is often better than a true cursor.