How to run raw SQL queries with Sequel
Asked Answered
H

2

21

I am not clear yet on the proper way to run raw SQL queries with Sequel.

Currently I am trying this:

DB.fetch("SELECT * FROM zone WHERE dialcode = '#{@dialcode}' LIMIT 1") do |row|
 @zonename = row
end

How can I can run the queries as raw SQL then access the results like normal?

if @zonename.name = "UK"
Hevesy answered 29/6, 2010 at 21:15 Comment(0)
S
16

I have a few pointers which may be useful:

  1. You could simply do:

     @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).first
    

NB: you are ignoring the fact that there could be more results matching the criteria. If you expect multiple possible rows to be returned then you probably want to build an array of results by doing ...

    @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).all

and processing all of them.

  1. The return set is a hash. If @zonename points to one of the records then you can do

     @zonename[:column_name] 
    

to refer to a field called "column_name". You can't do @zonename.column_name (you could actually decorate @zonename with helper methods using some meta-programming but let's ignore that for the moment).

Sequel is an excellent interface, the more you learn about it the more you'll like it.

Suspensoid answered 29/6, 2010 at 21:35 Comment(0)
M
22

Note that instead of:

DB.fetch("SELECT * FROM zone WHERE dialcode = '#{@dialcode}' LIMIT 1")

you should do:

DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode)

Otherwise, you open yourself to SQL injection if you don't control the contents of @dialcode.

Marpet answered 17/8, 2012 at 14:53 Comment(2)
Could you tell me what method is called by fetch under the hood to escape the user input? I have a complex query that is built up with many methods and need to escape the user input separately from my database call, while building the query.Melone
sorry, just found it in the docs (which I was reading while searching this, will post it here for others): github.com/jeremyevans/sequel/blob/… . The method is DB.literal(my_insecure_string). Thanks for the library Jeremy.Melone
S
16

I have a few pointers which may be useful:

  1. You could simply do:

     @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).first
    

NB: you are ignoring the fact that there could be more results matching the criteria. If you expect multiple possible rows to be returned then you probably want to build an array of results by doing ...

    @zonename = DB.fetch("SELECT * FROM zone WHERE dialcode = ? LIMIT 1", @dialcode).all

and processing all of them.

  1. The return set is a hash. If @zonename points to one of the records then you can do

     @zonename[:column_name] 
    

to refer to a field called "column_name". You can't do @zonename.column_name (you could actually decorate @zonename with helper methods using some meta-programming but let's ignore that for the moment).

Sequel is an excellent interface, the more you learn about it the more you'll like it.

Suspensoid answered 29/6, 2010 at 21:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.