Golang中MySQL的LOAD DATA为何未能加载全部记录
Golang中MySQL的LOAD DATA为何未能加载全部记录
LOAD DATA LOCAL INFILE <<filename>>
INTO TABLE savingaccount
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
SET mychoice = -99,rib_nonrib = -99,reportdate = <<reportdate>>
mysql.RegisterLocalFile(filePath)
rows, err := tx.Exec(sqlQuery)
if err != nil {
panic(err)
return err
}
没有加载所有行
更多关于Golang中MySQL的LOAD DATA为何未能加载全部记录的实战教程也可以访问 https://www.itying.com/category-94-b0.html
2 回复
它没有加载最后5或6条记录
更多关于Golang中MySQL的LOAD DATA为何未能加载全部记录的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go中使用LOAD DATA LOCAL INFILE时未能加载全部记录,通常是由于以下几个原因造成的:
1. 文件路径问题
确保<<filename>>是客户端机器上的有效路径,而不是服务器路径。使用mysql.RegisterLocalFile()注册文件时,路径必须与传递给SQL语句的路径完全匹配。
// 正确的做法
filePath := "/path/to/data.csv"
mysql.RegisterLocalFile(filePath)
sql := fmt.Sprintf(`LOAD DATA LOCAL INFILE '%s'
INTO TABLE savingaccount
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
SET mychoice = -99, rib_nonrib = -99, reportdate = '%s'`,
filePath, reportDate)
rows, err := tx.Exec(sql)
2. 字段数不匹配
CSV文件的列数必须与表结构匹配,或者通过SET子句处理额外的列:
// 如果文件有3列,但表有5列,需要明确指定
sql := `LOAD DATA LOCAL INFILE ?
INTO TABLE savingaccount
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
(col1, col2, col3) -- 明确指定文件中的列
SET mychoice = -99,
rib_nonrib = -99,
reportdate = ?,
col4 = DEFAULT, -- 处理缺失的列
col5 = DEFAULT`
3. 事务和错误处理问题
确保检查具体的错误信息,并使用RowsAffected()确认实际加载的行数:
mysql.RegisterLocalFile(filePath)
sql := fmt.Sprintf(`LOAD DATA LOCAL INFILE '%s'
INTO TABLE savingaccount
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 0 ROWS
SET mychoice = -99, rib_nonrib = -99, reportdate = '%s'`,
filePath, reportDate)
result, err := tx.Exec(sql)
if err != nil {
// 获取详细错误信息
log.Printf("LOAD DATA error: %v", err)
return err
}
// 检查实际影响的行数
rowsAffected, _ := result.RowsAffected()
log.Printf("Loaded %d rows", rowsAffected)
4. 字符编码问题
指定文件编码以确保正确解析:
sql := `LOAD DATA LOCAL INFILE ?
CHARACTER SET utf8mb4
INTO TABLE savingaccount
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
SET mychoice = -99, rib_nonrib = -99, reportdate = ?`
5. 完整的示例代码
import (
"database/sql"
"fmt"
"log"
_ "github.com/go-sql-driver/mysql"
"github.com/go-sql-driver/mysql"
)
func LoadDataFromFile(db *sql.DB, filePath string, reportDate string) error {
// 注册本地文件
mysql.RegisterLocalFile(filePath)
// 开始事务
tx, err := db.Begin()
if err != nil {
return err
}
defer tx.Rollback()
// 构建SQL语句
sql := fmt.Sprintf(`LOAD DATA LOCAL INFILE '%s'
INTO TABLE savingaccount
CHARACTER SET utf8mb4
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 0 ROWS
SET mychoice = -99, rib_nonrib = -99, reportdate = '%s'`,
filePath, reportDate)
// 执行LOAD DATA
result, err := tx.Exec(sql)
if err != nil {
log.Printf("LOAD DATA failed: %v", err)
return err
}
// 获取影响的行数
rowsAffected, err := result.RowsAffected()
if err != nil {
log.Printf("Failed to get rows affected: %v", err)
} else {
log.Printf("Successfully loaded %d rows", rowsAffected)
}
// 提交事务
if err := tx.Commit(); err != nil {
return err
}
return nil
}
6. 调试建议
添加错误日志记录,查看MySQL服务器的错误日志:
// 启用详细的MySQL日志
db.SetConnMaxLifetime(0)
db.SetMaxIdleConns(10)
db.SetMaxOpenConns(10)
// 执行前先验证文件存在性和可读性
if _, err := os.Stat(filePath); os.IsNotExist(err) {
return fmt.Errorf("file does not exist: %s", filePath)
}
检查MySQL服务器的SHOW WARNINGS输出,可以了解加载过程中被跳过的行及其原因。

