Search code examples
sqlrubysqlitebindsqlite3-ruby

syntax error when attempting to use bind vars in SQL queries in Ruby


I am using sqlite3 and attempting to pass bind variables into SQL statements in a command line application that I'm attempting as a replication of http://www.pangloss.com/seidel/shake_rule.html . This is the management utility for adding/removing from the database. I'm just trying to get an understanding of using SQL with Ruby and building a pen-and-paper rpg utility set for a DM whose game I'm currently playing.

db.execute ("INSERT INTO insults (position, string) VALUES (?, ?);",    cmd_args[1].to_i, cmd_args[2])

db.execute("SELECT * FROM insults WHERE position = ? AND string = ?;", cmd_args[1].to_i, cmd_args[2]) do |output|
  puts output
end

The first query causes a syntax error "unexpected ',', expecting ')'" and more errors which follow, but they disappear when I comment this line out.

The latter query does not seem fundamentally different, but it causes no errors when I comment out the former. It still does not output anything when I set the cmd_args array values manually. The database has some test elements in it, i.e. "1|test" which do not output, though no error is thrown.


Solution

  • You can't have a space between the method name and the opening parenthesis. Your first one:

    db.execute ("INSERT INTO insults (position, string) VALUES (?, ?);",    cmd_args[1].to_i, cmd_args[2])
    

    is interpreted more like this:

    x = ("INSERT ....", cms_args[1].to_i, cmd_args[2])
    db.execute x
    

    but constructs like (a, b, c) aren't legal Ruby syntax in that context and there's your syntax error.

    Your second one:

    db.execute("SELECT * ...", cmd_args[1].to_i, cmd_args[2]) do |output|
      puts output
    end
    

    should work fine so, presumably, your WHERE clause doesn't match anything so you don't get any results. Examine the contents of cmd_args and make sure that:

    1. You don't have any stray whitespace.
    2. Your arguments really are in cmd_args[1..2] rather than cmd_args[0..1].