0

我正在使用 Go 读取 CSV 文件并使用 go-odbc 将记录保存在 MS SQL 数据库中。它工作得很好,但我有一个问题,一些记录(大约 10 条记录)没有被存储。这是一个随机问题,有时 3 没有保存,有时 2 等等。保存所有记录的唯一时间是我放在fmt.Printf(" ")for 循环的末尾。请注意,它必须打印一个空格,它不能只是fmt.Printf(""). 我不确定我没有错。任何建议表示赞赏。此外,没有产生错误,程序正常终止。

我包含了相关问题的代码,如果您需要我发布整个代码,请告诉我。

Go 版本:go1.1 windows/amd64

for {
    record, err := c.Read()
    if err == io.EOF {
        break
    } else if err != nil {  
        fmt.Printf("Error while reading %s: %s\n", filename, err)
    } else {
        //replace the single quote at the beginning and end of string
        re, err := regexp.Compile("^'|'$")
        params := make([]interface{}, 0, numElements)
        valueHolders := make([]string, 0, numElements)
        tmpFields := make([]string, 0, numElements)
        count := 0

        for i:=1;i<=numElements;i++ {  
            tmp := re.ReplaceAllString(record[i],"")

            //insert only non-empty values
            if len(tmp) > 0 {
                params = params[0:count+1]
                params[count] = tmp

                valueHolders = valueHolders[0:count+1]
                valueHolders[count] = "?"

                tmpFields = tmpFields[0:count+1]
                tmpFields[count] = fieldNames[i-1]

                count++
            }
        }

        query := "insert into [l2test].[dbo]."+tablename+" (" + strings.Join(tmpFields, ",") + ") values (" + strings.Join(valueHolders, ",") + ")"
       stmt, err := dest.Prepare(query)

       if stmt == nil {
           fmt.Printf("Error preparing statment: %s\nQuery: %s\n%v\n\n", err, query, params)
       } else {
          stmt.Execute(params...)
          stmt.Close()
       }
   }

   fmt.Printf(" ")
}
4

1 回答 1

0

当您在最后删除一些元素时,通常是因为您从输入的末尾删除了它们,或者没有在输出时写入/刷新/提交/关闭它们。例如,在输入时,您可能会忽略 EOF 处的最后一个切片。我会以不同的方式编写您的 EOF 和错误测试。

数据库访问的错误处理也需要改进。例如,它应该检查错误。

一旦我们发现数据库访问错误,将一些诊断信息,例如queryrecord,添加到返回的错误 ( err) 中。

func insertRecord(conn *odbc.Connection, query string, params []interface{}) error {
    stmt, err := conn.Prepare(query)
    defer func() {
        if stmt != nil {
            stmt.Close()
        }
    }()
    if err != nil {
        return err
    }
    err = stmt.Execute(params...)
    if err != nil {
        return err
    }
    return nil
}

for {
    record, err := c.Read()
    if err != nil {
        if err != io.EOF {
            fmt.Printf("Error while reading %s: %s\n", filename, err)
            break
        }
        if len(record) == 0 {
            break
        }
    }

    // do things with a record

    query := "insert into [l2test].[dbo]." + tablename +
        " (" + strings.Join(tmpFields, ",") + ")" +
        " values (" + strings.Join(valueHolders, ",") + ")"
    err = insertRecord(dest, query, params)
    if err != nil {
        err = fmt.Errorf("%s\n%s\n%v\n%s", err, query, params, strings.Join(record, "||"))
        fmt.Println(err)
        continue
    }
}
于 2013-06-10T20:28:03.983 回答