found it

Following up on my post from a couple of days back, I found my invalid nulls today. There were null values where there shouldn’t have been on 20 records in a table of 100,000+. I fixed them. Tomorrow, I hope to zero in on whatever program bug is causing them to get in there in the first place.
A couple of quick observations:
First, SQL Profiler is my friend. There wasn’t really any way I could trace what the VB6 program was doing, and it wasn’t putting out enough error info for me to figure it out, but by following a SQL trace, I eventually isolated the problem records.
Second, I discovered Query ExPlus today, which turns out to be a pretty good tool if you need quick access to a SQL query tool on a machine where you can’t actually install the full SQL Management Studio.

how not to do error-handling

Currently working on a bug in an old VB6 system. The only thing we see in the logs is “Invalid use of Null”, which I know if the standard VB6 error you get when you try to access a value without checking to see if it’s null first. Since the system itself hasn’t changed in years, I know that, somewhere, in some table, there’s a null value where there shouldn’t be a null value. But, because the system doesn’t pass through the line # of the error, I can’t see which field it might be looking at. And, because it doesn’t pinpoint which record had the error, I can’t really tell which record it was processing when the error occurred. So, it could be any of about 100 different fields on any of about 100,000 different records. I’ve made an educated guess that it’s probably one of only a few different fields, and I think I’ve narrowed down the possible problem records too, but still, could I please ask anyone out there who may be writing non-trivial systems that may be in use long after they’ve left their company: If you’re going to “handle” exceptions, please do more than just eat them and report the error message! Please, for the love of god, at least report the line #. And, if you’re processing a large data set, give some indication of which record you were processing. Thank you.

GTD at work

At my previous job, we used Lotus Notes for e-mail, and I had a pretty reasonable system worked out for GTD with Lotus Notes.

I’ve been at my current job for about 5 months now. It’s finally starting to get complicated enough that I think I need to get my stuff a bit more organized, so I’m starting to play around with various GTD options.

We don’t have an internal e-mail server; instead, we use GMail. I’ve been using a fairly simple tag system with GMail: just an “!Action” tag and a “!Waiting For” tag, basically. The problem, of course, has been GMail’s threading. You can attach a tag to a conversation, but not a particular e-mail. This has become a problem recently, as I’ve gotten involved in a few e-mail threads with 10 or 20 messages, where maybe the fourth message was actionable, and the rest were not. That makes it hard to get to the action item easily.

I was about ready to give up on GMail, until I saw this blog post from a few days ago, announcing that it is now possible to turn off the “conversation view”. Well, I did that today, and I think it’ll help. One thing I miss from Lotus Notes is the ability to view messages individually, by default, but also being able to switch to a threaded view when I want to. With GMail, I guess I could switch “conversation view” back on if I wanted to see a thread, but it’s probably not a good idea to turn it on and off frequently. I’m guessing it would mess up the tags. Speaking of which, it does now seem possible to apply tags to individual messages, though they don’t specifically mention that in the blog post. That’s basically my key need in terms of being about to keep track of stuff in e-mail.

I also have my GMail account set up as an IMAP account in Thunderbird. I’ve thought about switching over to using that as my primary e-mail client, rather than the GMail web interface, but there are a few things I don’t like about it. It’s actually very good as a desktop client for GMail, in general. But I don’t entirely like the way it handles GMail labels. It shows them as IMAP folders, which is perfectly reasonable, but I can’t see any obvious way of see which folders a given e-mail is in, or to copy an e-mail into multiple folders at once (i.e. apply multiple GMail labels). (Again, here’s something I miss from Lotus Notes: the ability to right-click a message and select “show folders”.) The way GMail does labels, it’s always easy to see which labels are applied to a given message, and it’s fairly easy to apply (or remove) multiple labels.

One other tool I messed around with a bit today is ActiveInbox. It’s a Firefox add-in that adds some extra GTD functionality to GMail’s web interface. It looks pretty interesting, but I have to admit that I uninstalled it. I think I may give it another try later this week or maybe next week, if I can find some time to really figure it out.

I’ve also considered using Superstars instead of labels for my GTD “!Action” and “!Waiting For” indicators. That’s something I might play with at some point.

PowerShell script to view SMTP server WMI stats

I’ve been playing with PowerShell a bit lately. Here’s a script I wrote today that extracts some info about the standard Windows Server SMTP service, does a little formatting on it, and sends it out to someone via GMail. (I’m sending it via GMail, since the purpose of the script is to determine if there’s anything weird going on with the SMTP service, and if there is, then it doesn’t make sense to use it to send the status e-mail.)

function sendmail
{
    param ($msgtext)
    $EmailFrom = "someone@somewhere.com"
    $EmailTo = "someone@somewhere.com" 
    $Subject = "SMTP Stats" 
    $Body = $msgtext
    $SMTPServer = "smtp.gmail.com" 
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
    $SMTPClient.EnableSsl = $true 
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential("somebody@gmail.com", "password"); 
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
}

$smtp1 = gwmi Win32_PerfFormattedData_NTFSDRV_SMTPNTFSStoreDriver | ? { $_.Name -eq '_Total' }
$smtp2 = gwmi Win32_PerfFormattedData_SMTPSVC_SMTPServer | ? { $_.Name -eq '_Total' }
$Date = Get-Date
$output = "-----------------------------------------------`n" 
$output += "Stats from " + $smtp1.__SERVER + " on " + $date + "`n"
$output += "----------------------------------------------`n"
$output += "Messages in queue dir: " + $smtp1.Messagesinthequeuedirectory + "`n"
$output += "Remote queue length: " + $smtp2.RemoteQueueLength + "`n"
$output += "Remote retry queue length: " + $smtp2.RemoteRetryQueueLength + "`n"
$output += "`nBadmail:`n"
$output += "`tBadPickupFile: " + $smtp2.BadmailedMessagesBadPickupFile + "`n"
$output += "`tGeneralFailure: " + $smtp2.BadmailedMessagesGeneralFailure + "`n"
$output += "`tHopCountExceeded: " + $smtp2.BadmailedMessagesHopCountExceeded + "`n"
$output += "`tNDRofDSN: " + $smtp2.BadmailedMessagesNDRofDSN + "`n"
$output += "`tNoRecipients: " + $smtp2.BadmailedMessagesNoRecipients + "`n"
$output += "`tTriggeredviaEvent: " + $smtp2.BadmailedMessagesTriggeredviaEvent + "`n"
# $output
sendmail($output)

I still don’t really know PowerShell that well, but I’m learning. I picked up most of the info I needed to write this script from StackOverflow and Hey, Scripting Guy.

fun with stored procedures

I had some fun today optimizing a stored procedure. It was taking about 10 minutes to run, and I got it down to running in two seconds with a pretty minor change.

Without getting into too many gory details, it was basically doing a somewhat complicated PIVOT. It was using a SUM() call to generate a value that it was really just ignoring, just checking to see if it was null or not. I replaced the SUM() with a COUNT(), and checked for zero instead of null, and bam, 10 minutes down to 2 seconds.

This is the kind of stuff I really like doing — figuring out how to make a minor change in a bit of code that doesn’t affect the output, but results in a measurable improvement in performance. The only thing that’s still a little frustrating about this is that I don’t completely understand why the difference is so great. I have a general idea of why this worked, but something weird must be going on internally with the PIVOT option in MS SQL for this to have made such a huge difference.

my dad

Today is the one-year anniversary of my dad’s death. I considered a few things I might do today to remember and honor him. In the end, I decided to stay home and watch the Giants game, since that’s likely what he’d be doing today if he was still around.

I haven’t been down to my parents’ old house in a few weeks, and I really need to get down there are get some more stuff done, but I couldn’t quite talk myself into going down there today.

time for a new Kindle?

My Kindle 1 may be on its last legs. First, the battery doesn’t last long anymore. If it were only that, I’d just buy a new battery. But it’s also been locking up a lot lately. Thinking that this might just have something to do with my internal memory being almost full, I’ve moved nearly everything to the SD card. And today I deleted the system indexes from both the internal memory and SD card, to force the Kindle to recreate them. No clue if that will help. If it doesn’t, then I guess I’m going to be looking at the Kindle 3.

DropBox

I finally decided to switch from Windows Live Sync (aka FolderShare) to DropBox. I’ve got it installed on my desktop, Dell laptop, MacBook, and Acer netbook now, and I’ve moved everything from FolderShare to DropBox.

The main problem with FolderShare is that it doesn’t actually store any of your stuff, it just enables you to sync a folder between shared computers. So, to sync two computers, for instance, you need to have them both turned on and connected to the internet at the same time. For me, this has been leading to occasional problems, where I wind up with two versions of the same file, or I need to turn on my desktop computer to get the latest version of a file down to my laptop, for instance.

DropBox stores your stuff in the cloud, so it shouldn’t be a problem to get a shared file from one computer to another without needing them both on at the same time. We’ll see how it works in practice, but so far, so good.