views:

111

answers:

4

I've got a table with measurement data in SQL Server 2005, one value per person and year, if available. My TSQL code fetches these values in a loop and processes them:

...
SET @val = (SELECT measurement FROM tbl_data WHERE persid = @curpersid AND yr = @curyear)
...

Now, for a certain person and year, the table can contain (i) a valid measurement, (ii) a NULL value or (iii) no corresponding row at all.

How do I differentiate between these cases efficiently? Both (ii) and (iii) will result in @val being NULL, so with the current code, they can't be differentiated...

Thanks a bunch for any hints, wwwald

+1  A: 

Perhaps check @@ROWCOUNT? However, this is a little bit risky, as you need to be sure not to do any other operations before you check @@ROWCOUNT (it updated after most operations).

Alternatively, read another column, like the primary key:

SELECT @val = measurement, @id = id
FROM tbl_data WHERE persid = @curpersid AND yr = @curyear

now check @id - if it is NULL, there was no row.

Marc Gravell
I prefer to avoid the @@ROWCOUNT to make the code a bit more robust. If someone insert a query in between, the whole thing would break.
wwwald
I believe I both made that point and proposed a safer option?
Marc Gravell
Yes, definitely. I'll probably go for the COALESCE option (see below) since it allows me to continue using SET. Thanks for the idea, in any case!
wwwald
+2  A: 

If you can use a value that measurement can never take, COALESCE() can used.

SET @val = (SELECT COALESCE(measurement, someValueThatDoesNotOccur) FROM tbl_data WHERE persid = @curpersid AND yr = @curyear)

No row: @val == null

measurement was NULL: @val equals somevalue

else a vlaid measurement

Mitch Wheat
A: 

Well, it's a bit of a hack, but:

SET @val = -99999  -- or some other value that will never occur in the table
SELECT @val = measurement FROM tbl_data WHERE persid = @curpersid AND yr = @curyear

Now, if @val is still -9999 then there was no row, or null if the measurement was null.

Blorgbeard
Thanks, the COALESCE solution seems optimal for me. It also allows me to keep using SET, which will warn me when multiple rows are returned...
wwwald
+1  A: 

I question why you are looping at all? Looping is a bad thing in SQL Server as it is a performance killer. Most things have a better set-based solution. Perhaps your problem has a better solution if you tell us what you are doing in the loop besides setting the value of a variable.

HLGEM