Question

I've recently implemented a package that uses the database/sql package. By limiting the SQL to very simple select/update/insert statements I assumed the package would work with all the DBMS supported by database/sql.

However, it turns out that some databases use ? as placeholder value while others use $1, $2, etc., which means the prepared statements will work with some DBMS but not with others.

So I'm wondering is there any technique to make this work in a generic way with all the supported drivers? Or is it necessary to have DBMS-specific code everywhere? (which I think would make the abstraction provided by database/sql a bit pointless). I guess using non-prepared statements is not an option either since different DBMS have different ways to escape parameters.

Any suggestion?

Was it helpful?

Solution

I assume this behaviour was left out specifically because SQL dialects vary significantly between databases, and the Go team wanted to avoid writing a preprocessor for each driver to translate 'GoSQL' into native SQL. The database/sql package mostly provides connection wrangling, which is an abstraction that falls under 'pretty much necessary' instead of statement translation, which is more 'nice to have'.

That said, I agree that re-writing every statement is a major nuisance. It shouldn't be too hard to wrap the database/sql/driver.Prepare() method with a regex to substitute the standard placeholder with the native one, though, or provide a new interface that specifies an additional PrepareGeneric method that guesses a wrapped sql.DB flavour, and provides similar translation.

Gorp uses a dialect type for this, which may be worth a look.

Just throwing out ideas.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top