Golang SQL查询变量替换

10

我有一个 SQL 查询需要进行变量替换,以更好地消耗我的go-kit服务。

我有deporg作为用户输入,它们是我的 REST 服务的一部分,例如:dep = 'abc'org ='def'

我尝试了几种方法:

rows, err := db.Query(
    "select name from table where department='&dep' and organisation='&org'",
)

并且:

rows, err := db.Query(
    "select name from table where department=? and organisation=?", dep , org,
)

这导致出现错误:sql: statement expects 0 inputs; got 2

只有硬编码的值可以工作,替换失败。

我在 Oracle 博客中没有找到太多关于此的帮助,想知道是否有任何方法可以解决这个问题。


正确的方法是使用db.Query()db.Prepare()stmt.Exec()。但是,db.Query()不仅返回错误,请问你的驱动程序是什么?请提供一个包含db变量创建的代码示例。参考:https://golang.org/pkg/database/sql/#DB.Query - Rodrigo Brito
这是我的ORA驱动程序 - https://github.com/mattn/go-oci8 - Chakrapani Velugubantla
func NewOracleConnection(cfg config.Config, log log.Logger) (Connection, error) { var err error o := &Oracle{ Driver: cfg.DB.Driver, ConnectString: cfg.DB.ConnectString, logger: log, } o.Db, err = sql.Open(o.Driver, o.ConnectString) if err != nil { log.Log("event", "连接数据库", "err", err.Error()) } return o, err } - Chakrapani Velugubantla
我已经尝试了db.query和Exec。有趣的是,对于相同的带有变量替换的查询,sqlplus客户端可以正常工作,但使用这个驱动程序却失败了。 - Chakrapani Velugubantla
对于该驱动程序,似乎是 :N(https://github.com/mattn/go-oci8/blob/master/oci8Sql_test.go#L1149),其中 N 是参数的位置。因此,在您的情况下,应该像这样工作:db.Query("select name from table where department = :1 and organisation = :2", dep, org) - mkopriva
2个回答

21

参数占位符语法(参考:http://go-database-sql.org/prepared.html

预处理语句中的参数占位符语法因数据库而异。例如,比较MySQL、PostgreSQL和Oracle:

MySQL               PostgreSQL            Oracle
=====               ==========            ====== 
WHERE col = ?       WHERE col = $1        WHERE col = :col 
VALUES(?, ?, ?)     VALUES($1, $2, $3)    VALUES(:val1, :val2, :val3)

对于Oracle,您需要使用:dep、:org作为占位符。


3

正如@dakait所说,在您的prepare语句中,您应该使用:占位符。

因此,为了完整起见,您可以像这样使其工作:

package main

import (
    "database/sql"
    "fmt"
    "log"
)

// Output is an example struct
type Output struct {
    Name string
}

const (
    dep = "abc"
    org = "def"
)

func main() {

    query := "SELECT name from table WHERE department= :1 and organisation = :2"

    q, err := db.Prepare(query)
    if err != nil {
        log.Fatal(err)
    }

    defer q.Close()

    var out Output

    if err := q.QueryRow(dep, org).Scan(&out.Name); err != nil {
        log.Fatal(err)
    }

    fmt.Println(out.Name)

}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接