Mysql2::Error: You have an error in your SQL syntax - ruby-on-rails

I'm newby in ruby on rails, I have search textbox then everytime I type an apotraphe (') e.g testing' word ..... I always recieved error:
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 's word%' OR english_name LIKE '%testing's word%' OR chinese_name LIKE '%testin' at line 1: SELECT COUNT(DISTINCT `jos_store`.`id`) FROM `jos_store` LEFT OUTER JOIN (SELECT id as store_replenishment, store, MAX(stock_movement) AS stock_movement FROM jos_store_replenishment GROUP BY store) AS replenishment ON replenishment.store = jos_store.id LEFT OUTER JOIN jos_stock_movement ON jos_stock_movement.id = replenishment.stock_movement WHERE (store_id LIKE '%testing's word%' OR english_name LIKE '%testing's word%' OR chinese_name LIKE '%testing's word%')
can you help me with my problem.

Try escaping your apostrophe, eg english_name LIKE '%testing\'s word%'
if you're using '%PHRASE%' and there's another ' inside %PHRASE%, it thinks you've ended the like clause and gives you an error - if you escape with the escape character, eg \', it should work: so with your error phrase, something like:
<snip /> WHERE (store_id LIKE '%testing\'s word%' OR english_name LIKE '%testing\'s word%' OR chinese_name LIKE '%testing\'s word%')
Notice I've used '%testing\'s word%' to ensure it doesn't think the second apostrophe ends the LIKE clause

Related

EXECUTE FORMAT() USING in postgres is showing error for $

i will directly get to the code rather than explaining too much
execute format('
"$1" = select "Source1" from temp_tables._%s;
'::text, (translate("Song_Id_"::text, '-', '_')))
using "Source1__";
the table is dynamically created and the table name is all fine as i have used that table to insert some data into it. if i run this code, the error i am getting is
ERROR: syntax error at or near "$1"
LINE 1: $1 = select "Source1" from temp_tables._24af1593_3539_49fd_9...
^
QUERY: $1 = select "Source1" from temp_tables._24af1593_3539_49fd_9ef4_29307f301d38;
i have tried other method too like
execute
'$1 = select "Source1" from temp_tables._' || (translate("Song_Id_"::text, '-', '_')) ||';'
using "Source1__";
even this gives the same error.
note : "Source1__" is a variable of type text declared in the stored procedure where everything else is being executed too.
This is wrong. The EXECUTE command accepts only SQL statements. There is nothing statement like var = SELECT .... More - the you can pass just value by using clause USING. You cannot to pass any reference to variable. Solution is easy. Just use clause INTO
EXECUTE 'SELECT ... ' INTO target_plpgsql_variable
Please, read related documentation. Unfortunately, some parts the stored procedures are not extra intuitive because there is mix of two very different languages. It is good by reading documentation, because is hard to find correct solution without knowledge of possibilities and syntax.

Rails/Postgres nested JSON query

I have a JSON column in my events table called payload. I can create an event like this:
Event.create!(application_id: 1, stage: 'INITIATION', payload: { key: 'OUTCOME', value: {school_id: 2, prefered_language: 'GBP'}})
Simple queries like
Event.where("payload->>'key' = ?", "OUTCOME")
Will work fine, but how can I then add extra filters with the JSON that's nested in the value portion
Event.where("payload->>'key' = ? AND payload ->>'value'->>'school' = ?", "OUTCOME", 2)
^^^^^^^^^^^^^^^^^^^^
I tried that but i got:
PG::UndefinedFunction: ERROR: operator does not exist: text ->> unknown
LINE 1: ...ad ->>'key' = 'INPUTPARAMS' AND payload ->>'value'->>'school... ^
HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.
How do I get into the school attribute within value?
I have taken the idea from this documentation on ActiveRecord and JSON
After much searching, I came across this article.
The #>> operator allows you to dig inside the JSON. My query could be fixed like this.
Event.where("payload->>'key'= ? AND payload#>>'{value, school_id}' = ?", 'OUTCOME', shcool_id)
You could theoretically go down further by adding each layer to the predicate block {value, school, next_level, and_so_on}

wrong number of arguments (1 for 2..3) for Active Record postgresql query (Rails 4/postgresql 9.4) [duplicate]

Right now I am in the middle of migrating from SQLite to Postgresql and I came across this problem. The following prepared statement works with SQLite:
id = 5
st = ActiveRecord::Base.connection.raw_connection.prepare("DELETE FROM my_table WHERE id = ?")
st.execute(id)
st.close
Unfortunately it is not working with Postgresql - it throws an exception at line 2.
I was looking for solutions and came across this:
id = 5
require 'pg'
conn = PG::Connection.open(:dbname => 'my_db_development')
conn.prepare('statement1', 'DELETE FROM my_table WHERE id = $1')
conn.exec_prepared('statement1', [ id ])
This one fails at line 3. When I print the exception like this
rescue => ex
ex contains this
{"connection":{}}
Executing the SQL in a command line works. Any idea what I am doing wrong?
Thanks in advance!
If you want to use prepare like that then you'll need to make a couple changes:
The PostgreSQL driver wants to see numbered placeholders ($1, $2, ...) not question marks and you need to give your prepared statement a name:
ActiveRecord::Base.connection.raw_connection.prepare('some_name', "DELETE FROM my_table WHERE id = $1")
The calling sequence is prepare followed by exec_prepared:
connection = ActiveRecord::Base.connection.raw_connection
connection.prepare('some_name', "DELETE FROM my_table WHERE id = $1")
st = connection.exec_prepared('some_name', [ id ])
The above approach works for me with ActiveRecord and PostgreSQL, your PG::Connection.open version should work if you're connecting properly.
Another way is to do the quoting yourself:
conn = ActiveRecord::Base.connection
conn.execute(%Q{
delete from my_table
where id = #{conn.quote(id)}
})
That's the sort of thing that ActiveRecord is usually doing behind your back.
Directly interacting with the database tends to be a bit of a mess with Rails since the Rails people don't think you should ever do it.
If you really are just trying to delete a row without interference, you could use delete:
delete()
[...]
The row is simply removed with an SQL DELETE statement on the record’s primary key, and no callbacks are executed.
So you can just say this:
MyTable.delete(id)
and you'll send a simple delete from my_tables where id = ... into the database.

Selecting sum results from multiple tables in Rails

I am working in the Rails console. I would like to select the SUM of a same named column in two different tables.
Here is my ActiveRecord code:
Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST")
.group("computers.id")
This works well and returns the following correct SQL:
`SELECT computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST
FROM "computers" INNER JOIN "services" ON "services"."computer_id" = "computers"."id"
INNER JOIN "repairs" ON "repairs"."computer_id" = "computers"."id"
GROUP BY computers.id `
But it gives the following result in the Rails console:
=> [#<Computer id: 36>, #<Computer id: 32>]
Shouldn't I be able to access my SUM values as well? I ran the above SQL query in postgres and it gave the desired output.
Any help would be appreciated.
Thanks.
The Rails console uses the inspect method to display the object content. This method doesn't display the values for the custom fields. You will be able to print the value of a custom attribute at the console by explicitly referring to it.
Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as scost, SUM(repairs.cost) as rcost")
.group("computers.id").each do |c|
puts c.scost
puts c.rcost
end
Edit
Example based on comment:
Create a member variable in your controller:
#computers = Computer.joins(:services, :repairs)
.select("computers.id, SUM(services.cost) as scost, SUM(repairs.cost) as rcost")
.group("computers.id")
Iterate over the variable in your views
- #computers.each do |computer|
= computer.scost
= computer.rcost
Edit2
You need to use LEFT OUTER JOIN to get values for computers with missing repairs or services.
join_sql = "LEFT OUTER JOIN services ON services.computer_id = computers.id
LEFT OUTER JOIN repairs ON repairs.computer_id = computers.id"
sum_sql = "SUM(COALESCE(services.cost, 0)) as scost,
SUM(COALESCE(repairs.cost, 0)) as rcost"
#computers = Computer.joins(join_sql)
.select("computers.id, #{sum_sql}")
.group("computers.id")
try as follow,
#computer_list = Computer.joins(:services, :repairs).select("computers.id, SUM(services.cost) as SCOST, SUM(repairs.cost) as RCOST").group("computers.id")
#computer_list.last.SCOST

undefined method `gsub' for nil:NilClass

I'm newvbie in ruby on rails.. I'm having problem with gsub.. I everytime I go to the list of my store page it says "undefined method `gsub' for nil:NilClass"..
here is mycode :
def self.search(search_val, page = 1)
#search_val = search_val.gsub("'", "\\\\'")
search_query = "store_id LIKE '%#{ #search_val }%' OR english_name LIKE '%#{ #search_val }%' OR chinese_name LIKE '%#{ #search_val }%'"
select("jos_store.id, store_id, english_name, chinese_name, store_manager, delivery_area,year, week").joins("LEFT OUTER JOIN (SELECT id as store_replenishment, store, MAX(stock_movement) AS stock_movement FROM jos_store_replenishment GROUP BY store) AS replenishment ON replenishment.store = jos_store.id").joins("LEFT OUTER JOIN jos_stock_movement ON jos_stock_movement.id = replenishment.stock_movement").where(search_query).order("year DESC, week DESC").paginate :page => page, :per_page => 15
end
thanks in advance
A good practice is doing .to_s when you are using string methods.
You can use the & operator on search_val. It allows you to avoid null pointer exceptions without adding additional checks or using to_s to convert a string to a string.
So, you'll have something like this:
#search_val = search_val&.gsub("'", "\\\\'")
You can read more on the safe navigation operator here: http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/
This means that search_val is in fact nil. You can easily verify this by printing out the value of search_val.
I'm not sure if this is your case, but the same undefined method gsub for nil:NilClass error happened with me after a few rollbacks and migrations.
Then, I restarted the server and works. Maybe this could be the case for some people that reached this topic searching on Google.

Resources