如何使用goLang执行sql文件

aaj*_*aaj 10 database postgresql go

我有.sql文件,它有很多数据库创建,删除,填充的东西.是否可以使用可以执行sql文件的go函数.我使用postgres作为我的数据库,并使用lib/pq驱动程序进行所有数据库事务.但我在任何库中都可以在我的golang项目中执行这个sql文件.

swd*_*don 12

如果你要使用命令行来执行它,那就太麻烦了。您必须处理诸如设置密码、确保正确设置路径变量等问题。我认为最好的方法是使用数据库驱动程序并使用 Go 调用它。

在以下示例中,我使用了 Postgres的 sql 驱动程序的 pgx 实现。您可以使用您选择的任何驱动程序实现来实现。

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.
}
Run Code Online (Sandbox Code Playgroud)

解释:

  1. 以与操作系统无关的方式获取 sql 脚本的路径。
  2. 将文件内容读取为字符串。
  3. 使用sql驱动执行文件中的语句。

  • 必须在连接字符串中添加“?multiStatements=true”,否则您将收到“您的 SQL 语法有错误” (3认同)

May*_*tel 8

您可以使用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)
}
Run Code Online (Sandbox Code Playgroud)

  • 前提条件是安装了`psql`工具。 (2认同)

car*_*yte 7

我发现dotsql寻找类似的需求.您可以从特定文件加载命名的sql语句/ prepare语句并执行.

// 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()
Run Code Online (Sandbox Code Playgroud)

请参阅:https://github.com/gchaincl/dotsql


小智 5

您可以将文件拆分为单独的请求并逐个执行:

file, err := ioutil.ReadAll("/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
}
Run Code Online (Sandbox Code Playgroud)

  • 如果你的sql文件中有程序,它将无法工作. (3认同)
  • `requests:= strings.Split(string(file),";")`在这样的SQL情况下会断开:`INSERT INTO testtable(test)VALUES('abc; def');` (3认同)
  • 建议使用`strings.Split(string(file),“; \ n”)`来避免@GeneS提到的问题。 (2认同)

Dhi*_*aTN 5

这里你有 2 个选择:

  1. 使用 sql 驱动程序连接到数据库并执行 sql 语句:这里是使用附加事务的完整示例:

    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()
    }
    
    Run Code Online (Sandbox Code Playgroud)

用法:

loadSQLFile(db, "data/my_file.sql")
Run Code Online (Sandbox Code Playgroud)
  1. 执行 bash 命令的第二个选项:

    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()
    }
    
    Run Code Online (Sandbox Code Playgroud)

用法:

loadSQLFile("my_db", "my_user", "localhost", "data/my_file.sql")
Run Code Online (Sandbox Code Playgroud)

虽然第二个选项看起来更简单、更短,但我推荐第一个选项,它可以让您更好地控制自己所做的事情,最重要的是它更便携。