英文:
Creating generic code using database/sql package?
问题
我最近实现了一个使用database/sql
包的包。通过将SQL限制为非常简单的select/update/insert语句,我认为该包将适用于database/sql
支持的所有DBMS。
然而,事实证明,一些数据库使用?
作为占位符值,而其他数据库使用$1
、$2
等,这意味着预编译语句将适用于某些DBMS,但对其他DBMS则不适用。
所以我想知道是否有任何技术可以以通用方式与所有支持的驱动程序一起使用?或者是否有必要在每个地方都有特定于DBMS的代码?(我认为这会使database/sql
提供的抽象有点无意义)。我猜想使用非预编译语句也不是一个选择,因为不同的DBMS有不同的参数转义方式。
有什么建议吗?
英文:
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?
答案1
得分: 1
我认为这种行为被特意省略,因为不同数据库之间的SQL方言差异很大,Go团队希望避免为每个驱动程序编写预处理器,将'GoSQL'转换为本地SQL。database/sql包主要提供连接管理,这是一个在语句转换之前的抽象,而语句转换更多是“好有”的而不是“必须有”的。
话虽如此,我同意重新编写每个语句是一件很麻烦的事情。不过,用正则表达式包装database/sql/driver.Prepare()方法来替换标准占位符为本地占位符应该不难,或者提供一个新的接口,指定一个额外的PrepareGeneric方法来猜测包装的sql.DB类型,并提供类似的转换。
Gorp
在这方面使用了一个方言类型,值得一看。
只是随便提出一些想法。
英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论