12

I have sql query that needs variable substitution for better consumption of my go-kit service.

I have dep & org as user inputs which are part of my rest service, for instance: dep = 'abc' and org = 'def'.

I've tried few things like:

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

And:

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

That led to error: sql: statement expects 0 inputs; got 2

Only hard-coded values work and substitution fails .

I haven't found much help from oracle blogs regarding this and wondering if there is any way to approach this.

5
  • The right way is db.Query() or db.Prepare() with stmt.Exec(). But db.Query() does not return only error, whats is your driver? Please, complete with a sample of code with db variable creation. Reference: golang.org/pkg/database/sql/#DB.Query Commented Sep 15, 2018 at 0:00
  • here is my ora driver - github.com/mattn/go-oci8 Commented Sep 15, 2018 at 4:17
  • 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.Error()) } return o, err } Commented Sep 15, 2018 at 4:20
  • i have tried db.query & Exec. what's interesting is sqlplus client works fine for the same query with variable substitution but fails with this driver Commented Sep 15, 2018 at 4:21
  • For that driver it seems to be :N (github.com/mattn/go-oci8/blob/master/oci8Sql_test.go#L1149) where N is the position of the parameter. So in your case something like this should work: db.Query("select name from table where department = :1 and organisation = :2", dep, org) Commented Sep 15, 2018 at 8:18

2 Answers 2

26

Parameter Placeholder Syntax (reference: http://go-database-sql.org/prepared.html )

The syntax for placeholder parameters in prepared statements is database-specific. For example, comparing MySQL, PostgreSQL, and Oracle:

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

For oracle you need to use :dep, :org as placeholders.

Sign up to request clarification or add additional context in comments.

Comments

3

As @dakait stated, on your prepare statement you should use : placeholders.

So, for completeness, you would get it working with something like:

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)

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.