Hi,
I am trying to make a program that retrieves data from a database, changes the data and inserts the data into another table. I will know the columns/tables during runtime only. Here is what I have working so far. The only part I have not been able to figure out is how to change the values retrieved. Any help will be appreciated.
func ETL() {
dbconn, err := sql.Open("mssql", "server=localhost;user id=[gouser];password=[password];database=test;Trusted_Connection=yes;connection timeout=30;")
if err != nil {
log.Fatal(err)
}
rows, err := dbconn.Query("select name, address1, email from t_people")
cols, err := rows.Columns()
vals := make([]interface{}, len(cols))
for i := range cols {
var ii interface{}
vals[i] = &ii
}
for rows.Next() {
err = rows.Scan(vals...)
}
// vals["name"] = "New Name" ??????????
// vals["address1"] = "New Address" ??????????
// vals["email"] = "New Email" ??????????
tx, _ := dbconn.Begin()
stmt, txerr := tx.Prepare("insert into t_people_new(name, address1, email) values (?,?,?)")
if txerr != nil {
log.Fatal(txerr)
}
_, err = stmt.Exec(vals...)
if err != nil {
log.Fatal(err)
}
}
I would suggest setting up a specific struct for the table type. Here’s an example of what I believe you’re trying to do:
package main
import (
"database/sql"
"log"
)
type Person struct {
Name string
Addr string
Email string
}
func main() {
dbconn, err := sql.Open("mssql", "server=localhost;user id=[gouser];password=[password];database=test;Trusted_Connection=yes;connection timeout=30;")
if err != nil {
log.Fatal(err)
}
var people []*Person
rows, err := dbconn.Query("select name, address1, email from t_people")
if err != nil {
// Handle error
}
for rows.Next() {
var p Person
err := rows.Scan(&p.Name, &p.Addr, &p.Email)
if err != nil {
// Handle error
}
// Update attributes in struct here or further down below.
// p.Name = "New name"
people = append(people, &p)
}
if err := rows.Err(); err != nil {
// Handle error
}
// Update values of people or person here if not changed above.
people[0].Name = "New name for first person returned"
// Do insert here.
}
Oh ok. In your example you are selecting from t_people and trying to change columns of t_people. How at runtime will you know what fields and table to select from?
Also are you only ever retrieving 1 record at a time or multiple? If it’s a single record, you could use a map instead of interface. (Same with multiple but not as straight forward)
I will try this out tonight when I get home from work(and the kids are asleep). Thanks for taking the time to reply to my post. I really appreciate it.