douliwang6896
2019-07-29 04:50
浏览 92

如何正确扫描pq阵列?

In a PostgreSQL database I have a table:

| ORGANIZATION_ID | FACTOR_IDS   | CALCULATION_VALUES  |
|-----------------|--------------|---------------------|
| 1               | {1,2,3,4,5}  | {0,66.66,50,100,80} |
| 2               | NULL         | NULL                |
| 1               | {6,7,8,9,10} | {0,77.77,60,110,90} |

In Go I make a query to that table and then try to use the Scan method. Unfortunately I get an error:

Trace: runtime error: invalid memory address or nil pointer dereference

My code:

type Entry struct {
    OrganizationID int
    FactorIDS pq.Int64Array
    CalculationValues pq.Float64Array
}

rows, err = database.DBGORM.Raw(`SELECT * FROM ANALYTICS`, ID).Rows()

if err != nil {
    utils.Logger().Println(err)
    return
}

defer rows.Close()

for rows.Next() {
    var entry *Entry

    if err = rows.Scan(&entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues); err != nil {
        utils.Logger().Println(err) // <- RAISE ERROR
        return
    }

    if entry.FactorIDS != nil {
        for index, value := range factorID {
            // some code here
        }
    }
}

How can I fix this problem?

Also if I change the type from pq.Int64Array to *pq.Int64Array the Go compiler gives the error: Cannot range over data *pq.Int64Array for the code above.

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • doudiemei2013 2019-07-29 04:56
    已采纳

    The nil pointer dereference is on entry. Fix by changing entry from a pointer to a value:

    for rows.Next() {
        var entry Entry  // <--- change on this line
        ... remaining code as in question
    }
    
    打赏 评论
  • douhuanchi6586 2019-07-29 07:23

    It was panicking because of the these &entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues. As entry is of pointer type and you haven't initialize the memory to it. If you want the struct of pointer type you can initialize it like this:

    for rows.Next() {
        entry:=new(Entry)
    
        if err = rows.Scan(&entry.OrganizationID, &entry.FactorIDS, &entry.CalculationValues); err != nil {
            utils.Logger().Println(err) // <- RAISE ERROR
            return
        }
    
        if entry.FactorIDS != nil {
            for index, value := range factorID {
                // some code here
            }
        }
    }
    
    打赏 评论

相关推荐 更多相似问题