今天替换数据库修改sql执行语句时遇到的问题:rows.Next()内调用函数中执行查询后再执行更新,那么rows.nex执行第二次循环时,到函数内查询的地方就卡死了?
问题代码段
函数1 部分代码
for rows.Next() {
var id int
rows.Scan(&id)
ids = append(ids, id)
//fmt.Printf("读取:%d\n", id)
// 业务逻辑
childlist := GetOrganChildEnd(id, idsAll)
//fmt.Printf("s1: %v\n", childlist)
//下面这个函数开始执行查询和更新 也是出问题的地方
UpdateOrganGeoStr(id, childlist)
}
函数2
//换成oralce后执行第二次会卡住,情况不明,修改成第二种方案
func UpdateOrganGeoStr2(organ int, organs []int) bool {
type PharLatlng struct {
LngRef float64 `gorm:"column:LNGREF;type:decimal(11,6);comment:基准经度(deg)"`
LatRef float64 `gorm:"column:LATREF;type:decimal(11,6);comment:基准纬度(deg)"`
}
var selectList []PharLatlng
sql := `select LngRef as "LngRef", LatRef as "LatRef" from phar_define where Organ in (?)`
err := global.DB.Raw(sql, organs).Find(&selectList).Error
//如果下面的是执行更新则第二次执行,会在这个地方卡住,查询则不会卡住
if err != nil {
//c.JSON(http.StatusOK, vo.NewResp(utils.CodeFail, "数据查询失败", nil))
return false
}
var lngRef, latRef float64
var lngMin, latMin, lngMax, latMax float64 = 999, 999, 0, 0
for i := 0; i < len(selectList); i++ {
//selectList
lngRef = selectList[i].LngRef
latRef = selectList[i].LatRef
if lngRef < 0.01 || latRef < 0.01 {
continue
}
if lngRef < lngMin {
lngMin = lngRef
} else if lngRef > lngMax {
lngMax = lngRef
}
if latRef < latMin {
latMin = latRef
} else if latRef > latMax {
latMax = latRef
}
}
str := fmt.Sprintf("%.6f %.6f", lngMin, latMin)
geoStr := str
str = fmt.Sprintf("%.6f %.6f", lngMax, latMin)
geoStr += "," + str
str = fmt.Sprintf("%.6f %.6f", lngMax, latMax)
geoStr += "," + str
str = fmt.Sprintf("%.6f %.6f", lngMin, latMin)
geoStr += "," + str
geoStr = "POLYGON((" + geoStr + "))"
//换成查询就可以完整执行,更新则下次会卡住
//sql2 := fmt.Sprintf("select * from phar_define")
err =global.DB.Model(&po.SysDept{}).Where("dept_id", organ).Update("GeoStr",geoStr).Error
//err = global.DB.Exec(sql2).Error
if err != nil {
return false
}
return true
}
解决方案
找了半天没发现是什么原因,估计是oarcle11版本太低?rows.next()问题?或者是go对oracle数据库的操作有缺陷?又或者是下载的包有问题?
浪费了半天时间,决定换执行的步骤;既然下面的函数再不执行跟新的情况下可以全部循环执行完成,那就把所有的更新语句全部拿出来,等rows.next循环完成后,再遍历执行更新操作好了。最后还是用替代方案解决了这个问题。
函数1 部分代码
sqls :=[]string{}
for rows.Next() {
var id int
rows.Scan(&id)
ids = append(ids, id)
// 业务逻辑
childlist := GetOrganChildEnd(id, idsAll)
c_sql :=UpdateOrganGeoStr(id, childlist)
sqls= append(sqls, c_sql)
}
//循环执行更新操作
for i := 0; i < len(sqls); i++ {
if sqls[i] == ""{
c.JSON(http.StatusOK, vo.NewResp(utils.CodeFail, "更新单位范围数据失败", nil))
break
}else{
err = global.DB.Exec(sqls[i]).Error
if err != nil {
c.JSON(http.StatusOK, vo.NewResp(utils.CodeFail, "更新单位范围数据失败", nil))
break
}
}
}
函数2
func UpdateOrganGeoStr(organ int, organs []int) string {
type PharLatlng struct {
LngRef float64 `gorm:"column:LNGREF;type:decimal(11,6);comment:基准经度(deg)"`
LatRef float64 `gorm:"column:LATREF;type:decimal(11,6);comment:基准纬度(deg)"`
}
var selectList []PharLatlng
sql := `select LngRef as "LngRef", LatRef as "LatRef" from phar_define where Organ in (?)`
err := global.DB.Raw(sql, organs).Find(&selectList).Error
if err != nil {
//c.JSON(http.StatusOK, vo.NewResp(utils.CodeFail, "数据查询失败", nil))
return ""
}
var lngRef, latRef float64
var lngMin, latMin, lngMax, latMax float64 = 999, 999, 0, 0
for i := 0; i < len(selectList); i++ {
//selectList
lngRef = selectList[i].LngRef
latRef = selectList[i].LatRef
if lngRef < 0.01 || latRef < 0.01 {
continue
}
if lngRef < lngMin {
lngMin = lngRef
} else if lngRef > lngMax {
lngMax = lngRef
}
if latRef < latMin {
latMin = latRef
} else if latRef > latMax {
latMax = latRef
}
}
str := fmt.Sprintf("%.6f %.6f", lngMin, latMin)
geoStr := str
str = fmt.Sprintf("%.6f %.6f", lngMax, latMin)
geoStr += "," + str
str = fmt.Sprintf("%.6f %.6f", lngMax, latMax)
geoStr += "," + str
str = fmt.Sprintf("%.6f %.6f", lngMin, latMin)
geoStr += "," + str
geoStr = "POLYGON((" + geoStr + "))"
sql = fmt.Sprintf("update sys_dept set GeoStr='"+geoStr+"' where dept_id=%d", organ)
if err != nil {
return ""
}
return sql
}