SQL: avoiding hard-coding or magic numbers

后端 未结 11 1396
无人及你
无人及你 2020-12-14 17:18

Question: What are some other strategies on avoiding magic numbers or hard-coded values in your SQL scripts or stored procedures?

Consider a stored

相关标签:
11条回答
  • 2020-12-14 17:45

    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

    0 讨论(0)
  • 2020-12-14 17:47

    For situations like your status table, I create what I call "static" data sets. These tables contain data that

    • Is set and defined upon creation,
    • Never ever changes, and
    • Is ALWAYS the same, from database instance to database instance, with no exceptions

    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.

    0 讨论(0)
  • 2020-12-14 17:50

    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).

    0 讨论(0)
  • 2020-12-14 17:51

    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.

    0 讨论(0)
  • 2020-12-14 17:55

    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)

    0 讨论(0)
  • 2020-12-14 17:55

    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.

    0 讨论(0)
提交回复
热议问题