views:

226

answers:

6

Let's say I have a database column that should always be in uppercase.

Here are a couple of ideas:

1) Create a column constraint of: col = UPPER(col)

2) Create an before insert/update row trigger that sets: col = UPPER(col)

Usually the more constraints on your database data the better, and triggers can be mysterious and bad. Assume that the developers writing code are in the same organisation and so the code they write can be modified by us.

Which approach would you use and why?

It has to be uppercase because the data in question is actually always in uppercase (it's originally printed that way by various third-parties). There is no meaning in uppercase vs lowercase for this particular field.

A: 

Or increase coverage of automated tests, and avoid the extra load on the production server.

eglasius
+1  A: 

In most situations I would say (1), because as you pointed out, triggers can often be bad/weird (though not always). But when dealing with string case sensitivity, I tend to treat that as a special case and always fix it up at every step along the way. I'm not sure I have any concrete reasons for doing so, it just "feels" right. Probably because in most of the environments I've worked in at least, from a business logic standpoint FoO always equals foo always equals FOO.

Also, in this case it seems like less of a burden on the developer to say "FYI, all strings are stored in uppercase on the server" than to slap their wrist every time they forget. It's not like saying "FYI, every time you insert a price into the DB, sales tax will be added."

Rex M
+9  A: 

It depends why the column needs to be in upper case, but in general I'd go for the constraint.

I don't like stuff which changes my data when I insert it into the database. It means that I have a mismatch between what I wrote and what I will read the next time.

If the text has been entered by a user, consider adding an extra column which contains the upper case version. This way you always display the text how the user entered it

MatthieuF
Or just UPPER when you SELECT.
strager
@strager. if the column should always have only uppercase data, changing it once on insert is far smarter than doing it every time you select. If you are doing a lot of this type of data manipulation on your selects, you are wasting server resources. You also are going to have bugs when people forget to do it or are unawre of the requirement.
HLGEM
+1  A: 

This is best implemented as a constraint, it avoids extra load and does what you want - force the data to be in the format you require.

I think it's the wrong approach to force conversion in the database because data that can be converted with no loss of integrity should be handled in the database layer. If the case is insignificant then handle as such - and a constraint helps to catch errors.

Adding a case insensitive index maybe a better solution (cf. Database Case Insensitive Index)

Richard Harrison
Not all changes to data come from the application and thus they don't go through the data layer, putting the constraints only there is irresponsible if the rule must alawys be enforced. I can guarantee I'm not going through the data layer to add 1,000,000 new records or update all of the data for an exisitng client.
HLGEM
I meant that there should be a constraint and this must be in the database; however conversions with *no loss of integrity* can be in the database layer.
Richard Harrison
A: 

I would consider another approach also -- providing a "Table API" that allows developers to just pass values to a stored procedure (or whatever) which then ensures that the values are uppercase on insert (per your example). I would back this up with a constraint as well (it can aid query optimisation for one thing) and remove direct change privileges on the table -- if you don't trust developers to uppercase all the inserts then you shouldn't trust them to always use the TAPI either.

David Aldridge
A: 

IF you can do something in a column constraint on the database vice a trigger it is generally preferred as it is often faster. If you are talking about enforcing though the application, I do not recommend that. If the rule must always apply, it should never be anywhere except in the database. Things other than the application you are writing code for can change data in a database. Data integrity is the responsibilty of teh database, keep the code where it belongs to avoid problems.

HLGEM