Question: What are some other strategies on avoiding magic numbers or hard-coded values in your SQL scripts or stored procedures?
Consider a stored
One idea:
CREATE FUNC dbo.CONST_ACKNOWLEDGED()
RETURNS tinyint
AS
BEGIN
RETURN 3
END
However, it only makes sense if you don't have autonumber, IMHO
For situations like your status table, I create what I call "static" data sets. These tables contain data that
That is, at the same time you create the table, you populate it as well, using a script to ensure that the values are always the same. Thereafter, no matter what where or when the database, you will know what the values are, and can hard-code accordingly and appropriately. (I would never use surrogate keys or the identity column property in these situations.)
You do not have to use numbers, you can use strings -- or binaries or dates, or whatever is simplest, easiest, and most appropriate. (When I can, I use char strings--and not varchars--such as "RCVD", "DLVR", ACKN", and so forth are easier hard-coded values than, say, 0, 2, and 3.)
This system works for non-extensible sets of values. If these values can be modified (such that 0 no longer means "acknowledged", then you have a security access problem. If you have a system where new codes can be added by users, then you have a different and tricky design issue to resolve.
Imagine
table dbo.Status
(
Id int PK
,Description varchar
)
values
1, Received
2, Acknowledged
3, Under Review
etc
So, just
declare @StatusReceived int = 1
declare @StatusAcknowledged int = 2
declare @StatusUnderReview = 3
etc
As others mention, this assumes that IDENTITY is not set.
I too used to JOIN on lookup tables, but this keeps the SELECT shorter and easier to read.
This approach lends itself to automation, so I generate an entire table in a separate query, then copy over the elements I require (not all of them).
Don't rely on IDENTITY for all of your IDs. When you have a lookup table that's going to be less than 50 rows for example, it's perfectly reasonable to either define those lookups as having specific IDs or use a string valued code for them. In either case, "hard-coding" is no longer an issue.
This is how I would do it. (Because it is much faster than your example)
UPDATE SomeTable
SET CurrentStatusID = [Status].[ID]
FROM SomeTable
RIGHT JOIN [Status] ON [Name] = 'Acknowledged'
WHERE SomeTable.[ID] = @SomeID
(not tested could have typos)
If your case is as simple as above, where an IsAcknowledged bit would work, I would go that route. I've never had any problems with that. If you have more complicated scenarios, where you would end up with a dozen bit fields, I don't see any problem using a "magic number" as long as you are fully in control of it. If you are worried about the identity column not mapping correctly when you port the database, you could create another (non-identity) unique column with your ID values, integer or guid or whatever else would be helpful.