
# 完整示例
以DSN连接串，初始化employee表后批量插入数据，并获取插入结果输出结果集列信息为例：
```
// main.go
package main
import (
 "database/sql"
 "fmt"
 _ "gitee.com/opengauss/openGauss-connector-go-pq"
 "log"
 "os"
)
func main() {
 // 创建数据库对象
 hostip := os.Getenv("GOHOSTIP")                   // GOHOSTIP：写入环境变量的IP地址
 port := os.Getenv("GOPORT")                       // GOPORT：写入环境变量的port
 usrname := os.Getenv("GOUSRNAME")                 // GOUSRNAME：写入环境变量的用户名
 passwd := os.Getenv("GOPASSWD")                   // GOPASSWD：写入环境变量的用户密码
 dbname := os.Getenv("GODBNAME")                   // GODBNAME：写入环境变量的目标连接数据库名
 connect_timeout := os.Getenv("GOCONNECT_TIMEOUT") // GOCONNECT_TIMEOUT：写入环境变量的连接数据库超时时间
 socket_timeout := os.Getenv("GOSOCKET_TIMEOUT")   // GOSOCKET_TIMEOUT：写入环境变量的SQL最长的执行时间
 rootcertPath := os.Getenv("GOROOTCERT")           // GOROOTCERT：写入环境变量的根证书路径
 sslkeyPath := os.Getenv("GOSSLKEY")               // GOSSLKEY：写入环境变量的客户端证书的密钥路径
 sslcertPath := os.Getenv("GOSSLCERT")             // GOSSLCERT：写入环境变量的客户端SSL证书路径
 sslmode := os.Getenv("GOSSLMODE")                 // GOSSLMODE：写入环境变量的启用SSL加密的方式
dsn := fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s connect_timeout=%s socketTimeout=%s " +
   "sslmode=%s sslrootcert=%s sslkey=%s sslcert=%s target_session_attrs=master",
   hostip,
   port,
   usrname,
   passwd,
   dbname,
   connect_timeout,
   socket_timeout,
   sslmode,
   rootcertPath,
   sslkeyPath,
   sslcertPath,
)
 db, err := sql.Open("gaussdb", dsn)
 if err != nil {
  panic(err)
 }
 defer db.Close()
 err = db.Ping()
 if err != nil {
  panic(err)
 }
 fmt.Println("connect success.")
 // 开启事务
 tx, err := db.Begin()
 if err != nil {
  log.Fatal(err)
  return
 }
 // 初始化数据表
 _, err = tx.Exec("drop table if exists employee;")
 if err != nil {
  fmt.Println("drop table employee failed, err:", err)
  err = tx.Rollback() // 出错则回滚事务
  return
 }
 fmt.Println("drop table employee success.")
 _, err = tx.Exec("create table employee (id SERIAL PRIMARY KEY, name varchar(20), age int, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);")
 if err != nil {
  fmt.Println("create table employee failed, err:", err)
  err = tx.Rollback()
  return
 }
 fmt.Println("create table employee success.")
 // 批量插入数据
 employee := []struct {
  Name string
  Age  uint8
 }{{Name: "zhangsan", Age: 21}, {Name: "lisi", Age: 22}, {Name: "zhaowu", Age: 23}}
 batchSql := "INSERT INTO employee (name, age) VALUES "
 vals := []interface{}{}
 placeholders := "(?, ?)"
 for _, u := range employee {
  vals = append(vals, u.Name, u.Age)
 }
 stmt := batchSql + placeholders
 _, err = tx.Exec(stmt, vals...)
 if err != nil {
  fmt.Println("batch insert into table employee failed, err:", err)
  err = tx.Rollback()
  return
 }
 fmt.Println("batch insert into table employee success.")
 // 提交事务
 err = tx.Commit()
 if err != nil {
  fmt.Println("commit failed, err:", err)
  err = tx.Rollback()
  log.Fatal(err)
  return
 }
 fmt.Println("commit success.")
 // 获取结果集列信息
 rows, err := db.Query("SELECT id, name, created_at FROM employee;")
 if err != nil {
  fmt.Println("query table employee failed, err:", err)
  return
 }
 columns, err := rows.Columns()
 if err != nil {
  fmt.Println("get query rows columns failed, err:", err)
  return
 }
 fmt.Println("列数：", len(columns))
 fmt.Println("列名list：", columns)
 fmt.Println("--------------------------")
 // 获取列的类型信息
 columnTypes, err := rows.ColumnTypes()
 if err != nil {
  fmt.Println("get query rows ColumnTypes failed, err:", err)
  return
 }
 for _, ct := range columnTypes {
  fmt.Println("列名：", ct.Name())
  fmt.Println("数据库类型：", ct.DatabaseTypeName())
  length, ok := ct.Length()
  if ok {
   fmt.Println("长度：", length)
  }
  precision, scale, ok := ct.DecimalSize()
  if ok {
   fmt.Printf("精度/小数位数：%d/%d\n", precision, scale)
  }
  nullable, ok := ct.Nullable()
  if ok {
   fmt.Println("是否可为空：", nullable)
  }
  fmt.Println("Go 类型：", ct.ScanType())
  fmt.Println("-----")
 }
}
```
#### 结果验证
以下为[完整示例](https://support.huaweicloud.com/bestpractice-gaussdb/gaussdb-23-0145.html#ZH-CN_TOPIC_0000002663779941)的执行结果：
```
connect success.
drop table employee success.
create table employee success.
batch insert into table employee success.
commit success.
列数： 3
列名list： [id name created_at]
--------------------------
列名： id
数据库类型： INT4
Go 类型： int32
-----
列名： name
数据库类型： VARCHAR
长度： 20
Go 类型： string
-----
列名： created_at
数据库类型： TIMESTAMP
Go 类型： time.Time
-----
```
预期结果包含以下内容：
1. 拼接数据库连接串，通过sql.Open创建连接对象，并通过db.Ping()方法检测是否成功连接数据库。
2. 开启事务，并在事务中初始化测试表employee。
3. 在事务中构造employee测试数据，并生成批量插入SQL，通过事务对象提供的接口Exec，绑参并发送报文到数据库执行SQL。
4. 批量插入执行成功后，通过Commit接口提交事务。（如果执行失败通过Rollback接口回滚事务）。
5. 通过数据连接对象"db"提供的Query接口查询批量插入执行结果，并通过结果对象"rows"提供的Columns接口获取所有列名列表以及结果对象"rows"提供的ColumnTypes接口获取结果集列的元数据信息。
 
#### 回退方法
通过事务对象的Rollback接口，对事务内的操作进行回滚。
