I\'ll go first.
I\'m 100% in the set-operations camp. But what happens when the set logic on the entire desired input domain leads to a such a large retrieval that
If a table is un-indexed for some reason, a cursor will be faster than other methods of iterating over a table. I found this information in this blog post on cursors in SQL Server last year.
While the author is in favor of "use only as a last resort" approach (as is everyone here), she does find a case or two where cursors perform as well as other available alternatives (including the running totals pointed out by Robert Rossney). Among other interesting points she makes, she indicates that cursors operate more efficiently inside stored procedures than as ad-hoc queries. The author also does an excellent job of pointing out when the performance problems we all associate with cursors begin to occur.
The blog post contains actual code, so readers can try the queries themselves and see the results.
I've got plenty of cases where rows from a configuration table have to be read and code generated and executed, or in many meta-programming scenarios.
There are also cases when cursors simply outperform because the optimizer is not smart enough. In those cases, either there is meta-information in your head which is simply not revealed to the optimizer through the indexes or statistics on the tables, or the code is just so complicated that the joins (and usually, re-joins) simply can't be optimized in the way you can visualize them in a cursor-based fashion. In SQL Server 2005, I believe CTEs tend to make this look a lot simpler in the code, but whether the optimizer also sees them as simpler is hard to know - it comes down to comparing the execution plan to how you think it could be done most efficiently and making the call.
General rule - don't use a cursor unless necessary. But when necessary, don't give yourself a hard time about it.
There are lots of different cursor behaviors.
You should never use a cursor unless you can explain all of these options and which ones are on by default.
And so, I never do.
Instead, when I feel the urge to loop over something in T-SQL... I load it into a variable table, which is something like a LOCAL STATIC SCROLL cursor... except that it can be indexed and joined (edit: and the downside of preventing the use of parallelism).
Well one operation where cursors are better than sets is when calculating a running total and similar stuff.