Golang SQL 查询变量替换

Posted

技术标签:

【中文标题】Golang SQL 查询变量替换【英文标题】:Golang SQL query variable substituion 【发布时间】:2018-09-14 23:45:06 【问题描述】:

我的 sql 查询需要变量替换以更好地使用我的 go-kit 服务。

我有 deporg 作为用户输入,它们是我的休息服务的一部分,例如: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 变量创建的代码示例。参考:golang.org/pkg/database/sql/#DB.Query 这是我的 ora 驱动程序 - github.com/mattn/go-oci8 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", "connecting to database", "err", err.错误())返回o,错误 我试过 db.query & Exec。有趣的是 sqlplus 客户端对于具有变量替换的相同查询可以正常工作,但此驱动程序失败 对于该驱动程序,它似乎是:N (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) 【参考方案1】:

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

prepared statements 中占位符参数的语法是 特定于数据库。例如,比较 mysql、PostgreSQL 和 甲骨文:

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

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

【讨论】:

非常感谢..这绝对有帮助..我能够解决它..谢谢【参考方案2】:

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

因此,为了完整起见,您可以使用以下内容:

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)


【讨论】:

非常感谢..我能够用上面的例子和@dakait 的逻辑解决它

以上是关于Golang SQL 查询变量替换的主要内容,如果未能解决你的问题,请参考以下文章

读书笔记:SQL 查询中的SQL*Plus 替换变量(DEFINE变量)和参数

SQL 在查询结果中替换另一个表中的多个变量

使用 Oracle 替换变量进行查询

如何将 R 会话中的值替换为 SQL 绑定变量占位符?

thinkPHP替换SQL变量

PL/SQL 游标的变量/文字替换?