Database 如何执行sql文件
我有一个.sql文件,它有很多数据库创建、删除和填充的内容。是否可能有一个go函数来执行sql文件。我使用postgres作为我的数据库,并对所有数据库事务使用lib/pq驱动程序。但我对在我的Go项目中执行此sql文件的任何库都是开放的。您可以使用标准库的Database 如何执行sql文件,database,postgresql,go,Database,Postgresql,Go,我有一个.sql文件,它有很多数据库创建、删除和填充的内容。是否可能有一个go函数来执行sql文件。我使用postgres作为我的数据库,并对所有数据库事务使用lib/pq驱动程序。但我对在我的Go项目中执行此sql文件的任何库都是开放的。您可以使用标准库的os/exec包。不需要数据库驱动程序。postgreSQL的代码如下所示: cmd := exec.Command("psql", "-U", psqlUser, "-h", psqlHost, "-d", psqlDBName, "-a"
os/exec
包。不需要数据库驱动程序。postgreSQL的代码如下所示:
cmd := exec.Command("psql", "-U", psqlUser, "-h", psqlHost, "-d", psqlDBName, "-a", "-f", sqlFilePath)
var out, stderr bytes.Buffer
cmd.Stdout = &out
cmd.Stderr = &stderr
err := cmd.Run()
if err != nil {
log.Fatalf("Error executing query. Command Output: %+v\n: %+v, %v", out.String(), stderr.String(), err)
}
您可以将文件拆分为单独的请求,然后逐个执行:
file, err := ioutil.ReadFile("/some/path/to/file")
if err != nil {
// handle error
}
requests := strings.Split(string(file), ";")
for _, request := range requests {
result, err := db.Exec(request)
// do whatever you need with result and error
}
我在搜索类似需求时发现了dotsql。您可以从特定文件加载命名sql语句/准备语句并执行
// Get a database handle
db, err := sql.Open("sqlite3", ":memory:")
// Loads queries from file
dot, err := dotsql.LoadFromFile("queries.sql")
// Run queries
res, err := dot.Exec(db, "create-users-table")
res, err := dot.Exec(db, "create-user", "User Name", "main@example.com")
rows, err := dot.Query(db, "find-users-by-email", "main@example.com")
row, err := dot.QueryRow(db, "find-one-user-by-email", "user@example.com")
stmt, err := dot.Prepare(db, "drop-users-table")
result, err := stmt.Exec()
请参阅:如果要使用命令行执行它,会有很多麻烦。您必须处理诸如设置密码、确保正确设置路径变量等问题。我认为下注的方法是使用数据库驱动程序,然后使用Go调用它 在下面的示例中,我将用于Postgres。您可以选择任何驱动程序实现来实现
path := filepath.Join("path", "to", "script.sql")
c, ioErr := ioutil.ReadFile(path)
if ioErr != nil {
// handle error.
}
sql := string(c)
_, err := *pgx.Conn.Exec(sql)
if err != nil {
// handle error.
}
说明:
func loadSQLFile(db *sqlx.DB, sqlFile string) error {
file, err := ioutil.ReadFile(sqlFile)
if err != nil {
return err
}
tx, err := db.Begin()
if err != nil {
return err
}
defer func() {
tx.Rollback()
}()
for _, q := range strings.Split(string(file), ";") {
q := strings.TrimSpace(q)
if q == "" {
continue
}
if _, err := tx.Exec(q); err != nil {
return err
}
}
return tx.Commit()
}
loadSQLFile(db, "data/my_file.sql")
loadSQLFile("my_db", "my_user", "localhost", "data/my_file.sql")
func loadSQLFile(db, user, host, sqlFile string) error {
cmd := exec.Command("psql", "-U", user, "-h", host, "-d", db, "-a", "-q", "-f", sqlFile)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
return cmd.Run()
}
loadSQLFile(db, "data/my_file.sql")
loadSQLFile("my_db", "my_user", "localhost", "data/my_file.sql")
虽然第二个选项看起来更简单、更短,但我推荐第一个选项,它可以让您更好地控制自己的工作,最重要的是它更便于携带。这对我来说很有效
func loadSqlFile(db *sqlx.DB) {
// Read file
file, err := ioutil.ReadFile("./test/mock.sql")
if err != nil {
fmt.Println(err.Error())
}
// Execute all
_, err = db.Exec(string(file))
if err != nil {
fmt.Println(err.Error())
}
}
如果您的sql文件中有过程,它将不起作用。
请求:=strings.Split(string(file),“;”)
将在以下sql情况下中断:插入到testtable(test)值('abc;def')
建议使用strings.Split(string(file),“;\n”)
来避免@GeneS提到的问题。“;\n”
也适用于panic:Error 1065:Query为空
Error如果PLpgSQL中有触发器,这将不起作用,因为它需要解析BEGIN和END,等…先决条件是安装了psql
工具。