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输出,可以了解加载过程中被跳过的行及其原因。

回到顶部