Need to update a field within my mysql db. Would like to use the following query within rails:
update users set exported = TRUE where id = #{name[12]}
Currently, have the following:
db = Mysql2::Client.new( :host => 'localhost', :username => 'username', :password => 'password', :database => 'database')
results = db.query("select * from users where start_date is not NULL AND exported = 0").each(:as => :array)
results.each do |name|
db.query("update users set exported = TRUE where id = #{name[12]}")
end
index 12 is equal to the UID.
I would suggest that you use ActiveRecord for database calls when you are using Ruby on Rails.
I assume that you have at least a basic User model like this:
class User < ApplicationRecord
end
With an User model like that your query could look like this:
User.where.not(start_date: nil).where(exported: false).update_all(exported: true)
If you're using rails, I'd suggest using ActiveRecord. Your update will be:
#users = User.find(:all, :where => 'start_date is not null and exported = 0 and id = ?', name[12])
#users.each{ |user|
user.exported = true
user.save!
}
Hope that helps! Leave a comment if you need further help.
Related
Hey I am an absolute ruby noob and hope you could help me.
I want to do a lot of SQL-querys with different departments (Department A,B, C....)
I want to save the departments to an array and iteratethrough it, use loops and so on.
This is my old code:
#!/usr/bin/ruby
require 'mysql2'
##Connect to my Database
db = Mysql2::Client.new(:host => "localhost", :username => "MyUserName", :password => "MyPassword", :port => 3306, :database => "MyTest-Database" )
#Mysql querys
sql_A= "SELECT RMKPI FROM `Table1` WHERE `Department` = 'A' "
sql_B= "SELECT RMKPI FROM `Table1` WHERE `Department` = 'B' "
#Execute the querys
results_PO = db.query(sql_A)
results_DevMuM = db.query(sql_A)
This is my Pseudocode:
Array1[A,B,...]
loop
sql_Array1[x]="SELECT ...WHERE `Department`= Array1[x]"
Array1[x+1]
How can I do this?
Thanks a lot
DEPARTMENTS = %w|A B C|
results = DEPARTMENTS.map do |department|
query = "SELECT RMKPI FROM `Table1` WHERE `Department` = '#{department}'"
[department, db.query(query)]
end.to_h
Now you have a hash of { departments ⇒ results }. To access results for a given department, use:
results['A']
Sidenote: I would suggest you to google for ActiveRecord or any other ROM to simplify and make safer the work with database queries.
I'm trying to update my MySQL table but its throwing an error:
'SQLSTATE[HY093]: Invalid parameter number: parameter was not define'
Here is my code
$sql = "
UPDATE registration
SET fname, city, zip_code, state, tele_no, PayPal_email, mobile_no,address
VALUES :name, :city, :zip_code, :state, :tele_no, :PayPal_email, :mobile_no, :address
WHERE id = $id
";
$result = $stud->update($sql, array(":fname"=>$fn, ":city"=>$ct, ":zip_code"=>$zp, ":state"=>$st, ":tele_no"=>$off, ":PayPal_email"=>$pel, ":mobile_no"=>$mn, ":address"=>$ad));
Just try like this
$stm = $db->prepare($sql);
$stm->execute(array(":fname"=>$fn,":city"=>$ct,":zip_code"=>$zp,":state"=>$st,":tele_no"=>$off,":PayPal_email"=>$pel,":mobile_no"=>$mn,":address"=>$ad));
...
VALUES :name, ...
...
$result = $stud->update($sql, array(":fname" => $fn, ...
Your VALUES clause specifies a bind variable named :name, while the bind array you pass to execute() (and it should be execute(), not update()) specifies a bind variable named :fname. This is the cause of the specific error message you quoted.
You also have some errors in your syntax, so fixing that one problem won't fix everything. The correct syntax would be
$sql = "UPDATE registration
SET fname = :name,
city = :city,
zip_code = :zip_code,
state = :state,
tele_no = :tele_no,
PayPal_email = :PayPal_email,
mobile_no = :mobile_no,
address = :address
WHERE id = :id";
$stmt = $conn->prepare($sql);
$stmt->execute(array(':fname' => $fn, ':city' => $ct, ':zip_code' => $zp, ':state' => $st, ':tele_no' => $off, ':PayPal_email' => $pel, ':mobile_no' => $mn, ':address' => $ad, ':id' => $id));
Note that the argument $id is also passed to the WHERE clause through a bind variable.
As far as I know PDO uses following sinax:
$conn->executeQuery('SELECT * FROM <your_table> WHERE a = ? AND b = ?', [$aVariable, $bVariable]);
I mean that you should replace your :fname, :city etc to ?, and pass variables as a simple array [$fn, $ct, ...]
P.S. Since PHP 5.4 you can use the short array syntax, which replaces array() with [].
COMENT RELATED UPDATE:
As i found out You really can use named parameters, but you should bind them after query prepare:
$stmt->bindParam(":fname", $fn, PDO::PARAM_STR);
$stmt->bindParam(":city", $ct, PDO::PARAM_STR);
I am stuck with this for a couple of hours. It could be a quick solution but my brain is overheated now. Ok here it is.
I have Session and SessionType models which have many-to-many relationships to each other as follows.
class Session < ActiveRecord::Base
...
has_and_belongs_to_many :session_types
...
end
class SessionType < ActiveRecord::Base
...
has_and_belongs_to_many :sessions
...
end
What I want is to get a session which doesn't contain any specific session_type, eg.,
Session.find(:all, :joins => [:session_types], :conditions => ["session_types.id <> 44"])
It doesn't work for me since the above query will still give me the sessions which have session_types.id "44" in many of its associations because of the nature of many-to-many relationships.
Also the following mysql code doesn't work as well.
select sessions.* from sessions
INNER JOIN `session_types_sessions` ON `session_types_sessions`.session_id = `sessions`.id
WHERE ( session_types_sessions.session_type_id NOT IN (44))
GROUP BY sessions.id
Any help will be appreciated.
Thanks.
First select those sessions which are of type 44:
session_types_44 = Session.find(:all, :joins => :session_types,
:conditions => { :"session_types.id" => 44 }).uniq
and select sessions which do not fall into the above:
sessions_without_type_44 = Session.find(:all,
:conditions => "id NOT IN (#{session_types_44.join(",")})")
You need to be careful with that because if session_types_44 is empty array you will get SQL error.
And to answer your second question:
do you know how I could change the SQL to filter like "get me sessions which have session_type_id '43', but they must NOT have '44'
Take the result from sessions_without_type_44 and use it. First select SessionType with 43 and through association get all sessions which belong to that SessionType and their ids are within the sessions_without_type_44:
SessionType.find(43).sessions.all(:conditions => {
:id => sessions_without_type_44 })
Try this:
SELECT sessions.*
FROM sessions
LEFT JOIN session_types_sessions ON session_types_sessions.session_id = sessions.id AND session_types_sessions.session_type_id = 44
WHERE session_types_sessions.session_id IS NULL
Try this:
Session.all(
:include => :session_types,
:conditions => ["session_types.id IS NOT NULL AND session_types.id != ?", 44])
)
The include option uses LEFT JOIN hence this query will work.
I have a database with columns (username, points). I am making a call to return some fields from this database to use in a program. I want to pull:
The top 10 users with the most points
The 5 users above/below the username requesting the rankings
I can pull the top 10 easily enough...
top_users = UserPoints.find(
:all,
:conditions => ['points > 0'],
:order => "points DESC",
:limit => 10)
Pulling the specific entry for the username requesting is also easy with find_by_username, but how could I determine where this user is ranked? Then, how would you go about finding the 5 users above and 5 users below the specific user (assuming the user is not in the top 10)?
Thanks!
-mark
Maybe do it using two queries?
Users above current user:
UserPoints.all(:conditions => ['points > ?', user.points], :limit => 5, :order => 'points asc')
Users below current user:
UserPoints.all(:conditions => ['points < ?', user.points], :limit => 5, :order => 'points desc')
Maybe there is a way to do it using a single query, I am not an SQL expert, but this should solve it for you.
Rails and MySQL:
I have a table with several boolean columns representing tags. I want to find all the rows for which a specific one of these columns is 'true' (or I guess in the case of MySQL, '1'). I have the following code in my view.
#tag = params[:tag]
#supplies = Supply.find(:all,
:conditions=>["? IS NOT NULL and ? !=''", #tag, #tag], :order=>'name')
The #tag is being passed in from the url. Why is it then that I am instead getting all of my #supplies (i.e. every row) rather than just those that are true for the column for #tag.
Thanks!
If params[:tag] is set to foo, the find method is generating this query:
select * from supplies where 'foo' is not null and 'foo' != '' order by name;
This is returning all your Supply records because both conditions are always true.
'foo' is not null
'foo' != ''
Of course you're intending for params[:tag] to be a column name, but that is just terrible design.
You should have a tag attribute on your Supply model and use the following finder:
#supplies = Supply.all(:conditions => ["tag = ?", params[:tag]], :order => "name")
If you really want the ability for Supplies to have the option for multiple Tags, use:
class Supply < ActiveRecord::Base
has_and_belongs_to_many :tags
end
class Tag < ActiveRecord::Base
has_and_belongs_to_many :supplies
end
#supplies = Supplies.all(:conditions => {:tags => ['foo', 'bar']}, :order => "name")
I think this is what you want to do
#tag = params[:tag]
#supplies = Supply.find(:all, :conditions=>["? = ?", #tag, true], :order=>'name')