Quick Tip – Hybrid SELECT/INSERT/UPDATE/DELETE Scripts

If you're a DBA, especially one that has to deal with an ERP system that has no concept of silly things like "transactions", then you've probably got a collection of scripts to update and fix data as necessary.

And you probably (hopefully) run a SELECT before actually changing data, to visually confirm what will happen. You might do this by either having both a SELECT and UPDATE query in the script, or by commenting out the SELECT or UPDATE portions of the script as needed, or some other technique.

Here's an approach I've used for a few years now, which I've never seen mentioned elsewhere. This fictitious query would change the sales rep to 'Unassigned' for any customers with no orders in the past year.

SELECT
    cust.CustomerNumber,
    cust.CustomerName,
    cust.SalesRep
/*
UPDATE cust
SET SalesRep = 'Unassigned'
--*/
FROM Customers cust
    LEFT OUTER JOIN Orders ord
        ON cust.CustomerNumber = ord.CustomerNumber
        AND ord.OrderDate >= DATEADD(year, -1, GETDATE())
WHERE ord.OrderNo IS NULL

So what's going on? If you run the whole script, you get a SELECT query, since the UPDATE is commented out. If you highlight the line with UPDATE through the end of the query in order to execute only those lines (a nice feature of Management Studio), the script runs as an UPDATE statement. The magic happens in --*/. If you run the whole script, the -- is ignored as being inside the multi-line comment. If you run everything from UPDATE onward, the -- comments out the */, so there's no syntax error.

This also works with INSERT and DELETE statements; for an INSERT, you'll put the comment block before the SELECT list rather than after.

And if you want to be even more careful, replace UPDATE with BEGIN TRANSACTION; UPDATE.

Best of all, you don't have to maintain two identical queries, you don't have to worry about commenting/uncommenting the SELECT or UPDATE depending on what you need, and you don't have to worry about changing data if you accidentally run the whole script. Neat, huh?

Writing Well-Behaved Triggers

Triggers are an indispensible feature of SQL Server. Essentially stored procedures that are invoked automatically, a trigger can be used to perform logging, data validation and cleaning, synchronization, and notification, and implement referential integrity constraints that are too complicated for foreign keys, among, no doubt, plenty of other things.

But alas, any seasoned SQL Server DBA is probably familiar with the minefield of performance-related and other issues that can very easily stem from misuse or overuse of triggers. I've frequently been victim to (and perpetrator of) such issues myself.

So what does it take to write a good, well-behaved trigger? A surprising number of non-obvious things, that I'm going to address one at a time, by taking an example trigger from garbage to civilized. In a nutshell, here are the major concerns:

  1. Cut the chatter. Use NOCOUNT.
  2. Make sure your trigger can handle multiple rows.
  3. Prevent unbounded trigger cascading and recursion.
  4. Avoid horrible performance of the INSERTED and DELETED virtual tables.

Read more »

iPad (Or, “Why I Don’t Pack a Laptop Anymore”)

When the iPad was first announced way back in 2010, my reaction was much like many others’: “It’s just a big iPod Touch.” And at that point in time, that was a fair assessment. The first-generation iPad had a mere 256 MB of RAM, came with iOS 3.2, with no support for multitasking, or any of the other whiz-bang features that iOS 4 brought to the table later that year. My wife was enamored, and eventually got one about a year ago. Myself, I didn’t really see what the fuss was about.

Fast-forward a couple of years, and a lot has changed. The iPad 2 is equipped with 512 MB RAM and a dual-core CPU. iOS 5 has given the iPad (and iPhone) many features expected of a proper computer: multi-tasking, printing, PC-independence, and so on. In fact, so many of my day-to-day use cases are now addressed by the iPad, that my laptop mostly just sits around waiting to do Quicken duty, or copy some stuff to/from external storage. I can’t remember the last time it even left the house. I don’t need to lug around a big laptop all the time just in case I run into those outlier use cases. I’ll stick with extreme portability and astounding battery life, with 95% coverage of uses.

Now, you obviously can’t just take a new iPad out of the box, never install anything, and expect to get much real work done. For that, you’ll need to tap into the rapidly expanding software library. Here’s a short summary of what keeps my laptop at home.

Read more »