记一次debug的坑

感悟

这个故事告诉我们,永远不要相信自己的眼睛。

那天

天气晴朗,阳光明媚~
我用Go写了一段程序,程序中需要通过从文件中读取一段文字,然后拼入sql中,然后在数据库中执行。

由于我需要从文件中一行一行的读出数据,我用了这样子的方式读取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
func readLines(path string) (lines []string, err error) {
var (
file *os.File
part []byte
prefix bool
)
if file, err = os.Open(path); err != nil {
return
}
reader := bufio.NewReader(file)
buffer := bytes.NewBuffer(make([]byte, 1024))
for {
if part, prefix, err = reader.ReadLine(); err != nil {
break
}
buffer.Write(part)
if !prefix {
lines = append(lines, buffer.String())
buffer.Reset()
}
}
if err == io.EOF {
err = nil
}
return
}

调用的时候,我通过用了大概如下的代码:

1
2
3
4
5
6
7
8
9
10
11
lines, err := readLines(userFile)
if err != nil {
return
}
for _, line := range lines {
sqlStr := rawSql % line
_, err = dbConn.Exec(sqlStr)
if err != nil {
return
}
}

当然它报错了!这样子的错误信息~

1
Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

通过查阅,我发现这个near ‘’,是的竟然是空的,不像一般的写错sql语句一样是会写明错误信息~
瞬间我就神经开始大条了。

难道我后面写漏了什么?
怎么可能!
不,我得先去喝杯水,然后再来看看。
水果到了,再吃个苹果。
吃完洗个手-。-
我觉得没错啊!
F**k

结局

不玩了,之所以我会认为自己没错,是因为我将整个sql语句打印了出来,在肉眼确认没错之后,又去mysql得命令行中直接执行了语句,结果十分顺利。
最后,十分大条的将从文件中读取出来的lines用长度打印了出来,瞬间我就斯巴达了!

1
2
3
4
5
for _, line := range lines {
fmt.Printf("len[%s] is %d", line, len(line))
sqlStr := rawSql % line
fmt.Printf("sqlStr[%s] is %d", line, len(sqlStr))
}

结果。。。

1
2
len[*****] is 1024!
sqlStr[*****] is 1065!

这就是为什么我执行失败的原因!sqlStr里面,存在着一段空白的buffer!却是打印不出来的~
最后我把代码改成了这样~

1
2
3
4
5
data, err = ioutil.ReadAll(userFile)
if err != nil {
return
}
lines := strings.Split(string(data), "\n")

Done