Rails query to SQL statement - sql

I'm trying to write an write this:
Team.last.players.sum("goals")
erb:
SELECT SUM("players"."goals")
FROM "players"
WHERE "players"."team_id" = $1 [["team_id", 2]]
how to rewrite this so that I could use it in a method:
def sql_search
sql = "SELECT SUM \"players\".\"goals\" FROM \"players\" WHERE \"players\".\"team_id\" = $1 [[\"team_id\", #{self.id}"
connection.execute(sql);
end
keep getting this error:
PG::SyntaxError: ERROR: syntax error at or near "."
LINE 1: SELECT SUM "players"."goals" FROM "players" WHERE "players"....
Any ideas would be appreciated

You don't need to add \" in sql statement, just remove them.
def sql_search
sql = "SELECT sum(goals) FROM players WHERE team_id = #{self.id};"
connection.execute(sql);
end

Is there some reason that you want to hard code the SQL query? It's generally bad practice to use string interpolation to insert parameters to SQL queries because of SQL injection attacks. Instead it's recommended to use ActiveRecord's SQL query parameter binding like this:
user_input = 5
Player.where('team_id = ?', user_input).sum(:goals)
Basically what this does is insert the parameter 5 after sanitization. This means you're safe from attacks where a hacker attempts to insert arbitrary SQL into parameter variables attempting to return sensitive data or delete data entirely!

Related

Select Statement in SQLite Python - Using Variables in WHERE clause

Say I have a class variable restemail which stores the email id I need to use to sort out from the select statement in SQLite (Python). Whenever I refer to that variable after my WHERE clause, SQLite treats it as a column and returns an error saying that such a column doesn't exist. Something like this:
restemail=StringVar()
Password=StringVar()
def database(self):
conn = sqlite3.connect('data.db')
with conn:
cursor=conn.cursor()
strrest = self.restemail
cursor.execute('SELECT * FROM Restaurant3 WHERE restemail = strrest')
Can someone tell me how to use a variable inside my SQL queries without it being treated as a column name?
Any help will be appreciated.
Try the sqlite3 variable substitution syntax:
cursor.execute('SELECT * FROM Restaurant3 WHERE restemail = ?', (strrest,))

how to insert an array of strings to sql query in ruby

I have this query in ruby:
sql = "SELECT variants.id,
code,
regular_price,
price_before_sale
FROM variants
WHERE variants.code IN (#{context.codes.join(",")})"
where context.codes = ['PRDCT-1','PRDCT-2']
now context.codes becomes (PRDCT1,PRDCT2) inside the sql query because of the .join but what I want to happen is ('PRDCT1','PRDCT2') what am I missing?
EDI: I have tried to do (#{context.codes.join("','")}) but it returns (PRDCT1','PRDCT2)
Don't do that. Bobby Tables is watching. Instead, provide the adequate number of placeholders:
sql = "SELECT variants.id,
code,
regular_price,
price_before_sale
FROM variants
WHERE variants.code IN (#{context.codes.map { "?" }.join(",")})"
and then provide *context.codes in statement parameters.
I got it.
I added single quotes to ('#{context.codes.join("','")}')

? in ActiveRecord select

In a where statement, you can use variables like:
Order.where('employee_id = ?', params[:employee_id])
I'm trying to accomplish something similar with a select, but it's not working:
Order.select('amount FROM line_items WHERE employee_id = ? AS employee_line_items', params[:employee_id])
=> ERROR: syntax error at or near "1"
=> LINE 1: ...ployee_id" = ? AS employee_line_items, 1
What's going on here? Is it possible to use ? in select statement? If not, how can you insert an escaped sql string here? I'd like to just use #{params[:employee_id]}, but this bit of code would be vulnerable to sql injection.
You have to split your query and chain it:
Order.select('amount FROM line_items').where(['WHERE employee_id = ?', params[:employee_id]])
And also based on this question, I believe you cannot use AS in WHERE clause, only when selecting fields (and you can't use them in WHERE in any case)
Check the documentation to understand how select works on ActiveRecord models

chain string expression linq

In traditional sql we can chain expression according to if statements.
for example lets say I have variable called "firstName" and I want to get from database all users according to the value in this variable(if empty get all users)
so I will chain the sql string like that
string sql="";
if(firstname!="")
sql=String.format(" And firstname='{0}',firstName)
.ExecuteReader(System.Data.CommandType.Text,"select * from users where 1=1" + sql)
Is there a way to copy this Technique to linq expression?
something like
from U in user
where 1=1 & sql
select U
Change to method syntax instead of query syntax, and chaining is easy.
var query = user.Select(u => u);
if(firstname!="")
query = query.Where(u => u.firstname = firstname);
queries in query syntax are converted at compile-time, so there's not a mechanism to "inject" sql at run time using query syntax.

Perl DBI - binding a list

How do I bind a variable to a SQL set for an IN query in Perl DBI?
Example:
my #nature = ('TYPE1','TYPE2'); # This is normally populated from elsewhere
my $qh = $dbh->prepare(
"SELECT count(ref_no) FROM fm_fault WHERE nature IN ?"
) || die("Failed to prepare query: $DBI::errstr");
# Using the array here only takes the first entry in this example, using a array ref gives no result
# bind_param and named bind variables gives similar results
$qh->execute(#nature) || die("Failed to execute query: $DBI::errstr");
print $qh->fetchrow_array();
The result for the code as above results in only the count for TYPE1, while the required output is the sum of the count for TYPE1 and TYPE2. Replacing the bind entry with a reference to #nature (\#nature), results in 0 results.
The main use-case for this is to allow a user to check multiple options using something like a checkbox group and it is to return all the results. A work-around is to construct a string to insert into the query - it works, however it needs a whole lot of filtering to avoid SQL injection issues and it is ugly...
In my case, the database is Oracle, ideally I want a generic solution that isn't affected by the database.
There should be as many ? placeholders as there is elements in #nature, ie. in (?,?,..)
my #nature = ('TYPE1','TYPE2');
my $pholders = join ",", ("?") x #nature;
my $qh = $dbh->prepare(
"SELECT count(ref_no) FROM fm_fault WHERE nature IN ($pholders)"
) or die("Failed to prepare query: $DBI::errstr");