sql: ожидается 3 аргумента назначения в Scan, а не 1 в Golang - PullRequest
1 голос
/ 07 января 2020

Я пишу обобщенный код c для запроса данных из любой таблицы RDS. Я прошел через множество ответов StackOverflow, но ни один из них не помог мне. Я прошел по ссылкам ниже: -

Мой первый код

package main

import (
    "fmt"
)

type BA_Client struct {
    ClientId    int    `json:ClientId;"`
    CompanyName string `json:CompanyName;"`
    CreateDate  string `json:CreateDate;"`
}

func main() {

    conn, _ := getConnection() // Det database connection

    query := `select * from IMBookingApp.dbo.BA_Client
              ORDER BY
                ClientId ASC
              OFFSET 56 ROWS
              FETCH NEXT 10 ROWS ONLY ;`

    var p []byte
    err := conn.QueryRow(query).Scan(&p)
    if err != nil {
        fmt.Println("Error1", err)
    }

    fmt.Println("Data:", p)

    var m BA_Client
    err = json.Unmarshal(p, &m)
    if err != nil {
        fmt.Println("Error2", err)
    }

}

Мой второй код

conn, _ := getConnection()
query := `select * from IMBookingApp.dbo.BA_Client__c
          ORDER BY
            ClientId__c ASC
          OFFSET 56 ROWS
          FETCH NEXT 10 ROWS ONLY ;`

rows, err := conn.Query(query)
if err != nil {
    fmt.Println("Error:")
    log.Fatal(err)
}

println("rows", rows)

defer rows.Close()

columns, err := rows.Columns()
fmt.Println("columns", columns)

if err != nil {
    panic(err)
}

for rows.Next() {
    receiver := make([]*string, len(columns))

    err := rows.Scan(&receiver )
    if err != nil {
        fmt.Println("Error reading rows: " + err.Error())
    }
    fmt.Println("Data:", p)

    fmt.Println("receiver", receiver)
}

С обоими кодами я получаю ту же ошибку, что и ниже

sql: expected 3 destination arguments in Scan, not 1

Может ли это быть, потому что я использую SQL Сервер, а не MySQL? Спасибо, если кто-нибудь может помочь мне найти проблему.

Ответы [ 2 ]

1 голос
/ 07 января 2020

Если вы хотите использовать срез входных данных для сканирования строки, используйте переменную c 3-точечную нотацию ..., чтобы преобразовать срез в отдельные параметры, например:

err := rows.Scan(receiver...)

Ваши (три в данном случае) столбцы, использующие аргументы variadi c, будут эффективно расширяться следующим образом:

// len(receiver) == 3
err := rows.Scan(receiver[0], receiver[1], receiver[2])

EDIT :

SQL Значения параметров метода сканирования должны быть типа interface{}. Итак, нам нужен промежуточный срез. Например:

is := make([]interface{}, len(receiver))
for i := range is {
    is[i] = receiver[i]

    // each is[i] will be of type interface{} - compatible with Scan()
    // using the underlying concrete `*string` values from `receiver`
}

// ...

err := rows.Scan(is...)

// `receiver` will contain the actual `*string` typed items
0 голосов
/ 07 января 2020

попробуйте это (без амперсанда перед приемником) для второго примера:

err := rows.Scan(receiver)

receiver и *string уже являются ссылочными типами. Нет необходимости добавлять еще одну ссылку на него.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...