gpt4 book ai didi

postgresql - 直接从文件或字符串在 Go 中执行 SQL 脚本

转载 作者:IT王子 更新时间:2023-10-29 00:42:22 42 4
gpt4 key购买 nike

在我的应用程序安装脚本中,我正在检查数据库是否包含任何表。如果数据库为空,我有要运行的 DML 和 DDL SQL 脚本。

它从单独的 .sql 文件读取 SQL 并不重要,所以现在我只是将它直接放入两个字符串中 - 一个用于 DDL,一个用于 DML - 并将它们连接起来。

我现在的问题是,当我尝试运行用于生成表并使用 .Exec(sqlStr) 向其中插入数据的脚本时,我现在遇到了这个错误:

"pq: cannot insert multiple commands into a prepared statement"

我当然可以做一个解决方法。像这样的东西:

sqlStr := sqlDML + sqlDDL
sqlStmtSlice := strings.Split(sqlStr, ";")
for i:= 0; i < len(sqlStmtSlice) i++ {
// Exec() each individual statement!
}

但是,我不确定我是否喜欢这种方法。肯定有更好的方法来从文件中加载 SQL 脚本并执行整个批处理,对吧?你知道吗?

附言。我正在为 Go 使用 PostgreSQL 驱动程序,但我认为这没有任何区别。

编辑:

由于当时似乎没有更好的解决方案来完成这件事,所以我对上面的伪代码做了一点改进,经过测试,似乎工作得很好:

tx, err := db.Begin()

sqlStr := fmt.Sprintf(sqlDML + sqlDDL)
sqlStmtSlice := strings.Split(sqlStr, ";\r")

if err != nil {
return err
}

defer func() {
_ = tx.Rollback()
}()

for _, q := range sqlStmtSlice {
_, err := tx.Exec(q)

if err != nil {
return err
}
}

err = tx.Commit()

最佳答案

据我所知,如果不允许多语句查询,没有真正更好的方法。它与您使用的驱动程序无关,因为这是 database/sql 包限制。争论它是否是一个好的设计是另一个问题(我相信已经有很多人了)。

在备选方案方面,您可能会使用 SQL 架构迁移工具或从中汲取灵感。一般约定是使用语义惰性标记,例如评论,并围绕主题进行拆分。

golang中的例子,可以看:

  • goose : 功能齐全,迁移可以用 Go 编写
  • rambler : 轻量级,仅 SQL

免责声明:我是 rambler 的开发者。也就是说,您绝对应该看看 goose,它真的很酷。

关于postgresql - 直接从文件或字符串在 Go 中执行 SQL 脚本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28832831/

42 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com