使用Golang将数组中的行批量插入到SQL Server中。

huangapple go评论88阅读模式
英文:

Bulk insert rows from an array to an sql server with golang

问题

我有一个结构体列表,如下所示:

row = [
   {
      "name": <name1>,
      "age" : <age1>,
      "job" : <job1>
   },
   {
      "name": <name2>,
      "age" : <age2>,
      "job" : <job2>
   },
   {
      "name": <name3>,
      "age" : <age3>,
      "job" : <job3>
   },
   等等...
]

我想将这些数据插入到一个 SQL 表中。到目前为止,我通过循环遍历数组,并逐个插入每一行。但是是否有其他方法可以使用一条查询插入所有行?我知道可以使用批量插入,但我理解的是,批量插入需要从外部文件导入数据。我不想这样做。如何使用这个数组中的数据进行批量插入?

英文:

I have a list of structs as follows

row = [
   {
      &quot;name&quot;:&lt;name1&gt;,
      &quot;age&quot; :&lt;age1&gt;,
      &quot;job&quot; :&lt;job1&gt;
   },
   {
      &quot;name&quot;:&lt;name1&gt;,
      &quot;age&quot; :&lt;age1&gt;,
      &quot;job&quot; :&lt;job1&gt;
   },
   {
      &quot;name&quot;:&lt;name1&gt;,
      &quot;age&quot; :&lt;age1&gt;,
      &quot;job&quot; :&lt;job1&gt;
   },
   etc...
]

I want to insert this into an SQL table. So far I was running a loop through the array and inserting each row one by one. But is there any other way by which I can insert all the rows with just one query? I know bulk insert, but my understanding is that, for bulk insert, I will have to import data from an external file. I don't want to do that. How do I use the data from this array and perform bulk insert?

答案1

得分: 2

type Person struct {
	Name string
	Age  int
	Job  string
}

func InsertPeople(db *sql.DB, personSlice []*Person) error {
	var queryString = `INSERT INTO "person_table" (
		"name"
		, "age"
		, "job"
	) VALUES `

    numOfFields := 3
	params := make([]interface{}, len(personSlice)*numOfFields)
	for i, p := range personSlice {
		pos := i * numOfFields
		params[pos+0] = p.Name
		params[pos+1] = p.Age
		params[pos+2] = p.Job

		queryString += `(?, ?, ?),`
	}

	queryString = queryString[:len(queryString)-1] // 去掉最后一个逗号

	_, err := db.Exec(queryString, params...)
	return err
}

以上是一个用于将多个Person对象插入数据库的Go代码示例。该代码定义了一个名为Person的结构体,包含Name、Age和Job字段。InsertPeople函数接受一个指向sql.DB的指针和一个Person对象的切片作为参数,将这些对象插入到名为"person_table"的数据库表中。

在函数内部,我们首先构建了一个插入语句的查询字符串,然后使用params切片来存储所有要插入的参数值。通过遍历personSlice切片,我们将每个Person对象的字段值添加到params切片中,并在查询字符串中构建相应的占位符。

最后,我们执行数据库查询并返回可能出现的错误。

请注意,代码中的&quot;是HTML实体编码,实际代码中应该使用双引号"

英文:
type Person struct {
	Name string
	Age  int
	Job  string
}

func InsertPeople(db *sql.DB, personSlice []*Person) error {
	var queryString = `INSERT INTO &quot;person_table&quot; (
		&quot;name&quot;
		, &quot;age&quot;
		, &quot;job&quot;
	) VALUES `

    numOfFields := 3
	params := make([]interface{}, len(personSlice)*numOfFields)
	for i, p := range personSlice {
		pos := i * numOfFields
		params[pos+0] = p.Name
		params[pos+1] = p.Age
		params[pos+2] = p.Job

		queryString += `(?, ?, ?),`
	}

	queryString = queryString[:len(queryString)-1] // drop last comma

	_, err := db.Exec(queryString, params...)
	return err
}

答案2

得分: 0

你无法在不将文件放在服务器上的情况下进行任何类型的超优化批量插入。

我不确定数据库库是否支持,但使用SQLX扩展,你可以构建一个带有命名绑定变量的单个插入语句,该语句针对一个结构体。然后,你可以将这些结构体的数组传递给类似NamedExec的方法。

类似这样的代码:

users := []User{
  {
    Name: "alex",
    Email: "alex@example.com",
  },
  {
    Name: "muhammed",
    Email: "muhammed@example.com",
  },
}

db.NamedExec("insert into users (NAME, EMAIL) values (:Name, :Email);", users)

请注意,这只是一个示例,你需要根据你的实际情况进行适当的修改。

英文:

You aren't going to be able to do any kind of super-optimized bulk insert without placing a file on the server I don't think.

I am not sure if the db library supports it but using the SQLX extension you can build a single insert statement with named bindvars that go against a struct. You can then pass an array of these structs to a method like NamedExec.

Something like this:

users := []User{
  {
    Name: &quot;alex&quot;,
    Email: &quot;alex@example.com&quot;,
   },
   {
    Name: &quot;muhammed&quot;,
    Email: &quot;muhammed@example.com&quot;,
   },
}

db.NamedExec(&quot;insert into users (NAME, EMAIL) values (:Name, :Email);&quot;, users)

huangapple
  • 本文由 发表于 2021年9月17日 12:00:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/69217606.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定