ODBC does abstract the queries you need to make to a large extent, which means that the same code will work with many different database back-ends.

There are a number of problems though - you need a specific ODBC driver for each back-end that you want to use. Also ODBC has a number of levels which support different features. Your chosen backend may not support those features, or may not have a driver of sufficient level to support them.

Proprietary DB features are unlikely to be available via ODBC (not that you'd want to use them if you want to be back-end independant).

As Sealeopard points out, some SQL may be interpreted differently.

You can work around these issues or avoid problematic SQL to produce code which is completely back-end independant. If your requirements are simple enough then it's no big task.

However what usually happens in real life is that you code for your primary development back-end, then add exceptions when it doesn't work for the alternatives.

Don't let that put you off though - coding via ODBC is still a good solution if you may want to change the back-end. At best you will not have to make any change at all, at worst the number of changes will still be less than if you'd used a propritary interface.