Getting Error after converting mysql query to postgresql - mysql

$ Customer.send("today").count
SELECT COUNT(*) FROM "customers" WHERE (`customers`.created_at >
'2014-02-07 05:00:00.000000')
ActiveRecord::StatementInvalid: PG::SyntaxError: ERROR: syntax error
at or near "."
LINE 1: ...LECT COUNT(*) FROM "customers" WHERE (`customers`.created_at > '2014-02-07 05:00:00.000000')
When I convert my MYSQL database to PG then I m getting this error how can I fix this. If I right this query in MySQL then it's working fine but in PG getting error.
Help me Please...!
Thanks In Advance

Backticks for quoting is a MySQL-ism, standard SQL and PostgreSQL use double quotes for quoting identifiers. Somewhere you have:
where('`customers`.created_at > ?', something)
but PostgreSQL wants to see:
where('"customers".created_at > ?', something)
However, since the table name is lower case and not a reserved word, you can drop the quotes and get something that is both easier to read and will work in both databases:
where('customers.created_at > ?', something)
Presumably this change needs to be made inside the send scope.

Related

MySQL error: expecting EOF ";" instead of ")"

I have this code:
SELECT
date_created,
serial_number,
dense_rank() OVER ( PARTITION BY serial_number ORDER BY date_created DESC) AS "rank",
FROM table_A
;
And I am getting this error:
")" is not valid at this position, expecting EOF, ";"
I don't understadn why I am getting this error, I take the syntax from this web:
https://www.geeksforgeeks.org/mysql-partition-by-clause/
I already tried taking of the comma after "rank", because as far as I know there shouldn't be commas before the FROM statement. But the same error appears.
Any idea of what's happening?
EDIT: it is popssible that I cannot use dense_rank() because my user in this database doesn't have the permission to do that? There are many things I cannot do (for example to use INTO OUTFILE). Maybe I cannot use windows and first of all it doesn't recognize dense_rank(). In addition, the keyword "OVER" doesn't appear in blue in my MySQL Workbench.
The error comes to the fact that I am using the 5.7 version and windows functions were introduced in the 8 version.

Converting raw laravel mysql json query into postgres syntax

I have the following query that works in MYSQL
$query->whereRaw('
ST_Distance_Sphere(
point(address->>"$.longitude", address->>"$.latitude"),
point(?, ?)
) * .000621371192 < ?
', [$longitude, $latitude, $distance]);
When i deployed to heroku im getting this error
SQLSTATE[42703]: Undefined column: 7 ERROR: column "$.longitude" does not exist
LINE 3: point(address->>"$.longitude", address->>"$.latitu...
Im using postgres on heroku and i know the issue is something to do with the json operator.
What is the $.<json key> syntax called? and how do i convert this raw sql query to postgres?
In the worse case i leaning on switching my database to mysql if i cant solve this by Wednesday as it wont be a big deal
Postgres uses double quotes as delimiter for columns, so you must use single quotes to indicate strings. Laravel will take care of it
st_distance_sphere(
st_point(address->>'$.longitude',address->>'$.latitude'),st_point(?, ?)
)

Rails: MySQL2 Error when hitting the finder of a model

with Rails I hit this:
User.find(:all, :conditions => ["character = ?", character])
character is a Fixnum, as you can see by the way it is translated for the sql. A Fixnum is expected.
Then I get this 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 '= 5)'
at line 1: SELECT `users`.* FROM `users` WHERE (character = 5)
I'm somewhat confused and absolutely do not get what might be wrong with this line of sql.
Please help.
Yours
Joern
The problem is that character is a keyword in mysql. If you escape it in backticks it should work, eg
User.find(:all, :conditions => ["`character` = ?", character])
When you do a rails find like
User.where(:character => character)
as Rich Peck suggests, then rails automatically escapes the names of all fields to prevent this problem: you can see it do this in your log.
EDIT: you might find it less hassle in the long run to change the name of your column.
ActiveRecord
If using Rails 4, you should use this to look up multiple records:
User.where character: character
If you want to load a specific record, you can just use .find like this:
User.find_by character: character
--
Specific
I think your error is more an ActiveRecord issue than a Fixnum one - the fact you're using that data to look up the records shouldn't have any bearing.
I could be wrong, but I think the bottom line is your use of the ActiveRecord methods you've defined.

Rails & MySQL: SELECT Statement Single vs. Double Quotes

I have a CRON job which executes a SELECT statement to grab records. When the SELECT runs on my dev machine, it produces the following statement:
SELECT `users`.* FROM `users` WHERE `users`.`id` = 87 LIMIT 1
This is successful.
When the SELECT runs on my production (hosted) machine it produces the statement with double quotes:
SELECT "users".* FROM "users" WHERE "users”.”id” = 87 LIMIT 1
This is not successful and I get a MySQL 1064 error,
#1064 - 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 '.* FROM "users" WHERE "users
The code is the same on both machines, but my dev MySQL is version 5.5.33, whereas production is 5.1.67 (I don't have control over this to set/update it)
Is there a way to force single quotes or another preferred method to handle this situation?
Thanks for your time and assistance.
--EDIT--
Here are the main code snippets that are invoked via my CRON job:
/lib/tasks/reports.rake
namespace :report do
desc "Send Daily Report"
task :daily => :environment do
User.where(:report_daily => 1).find_each do |user|
ReportsMailer.send_report(user, 'daily').deliver
end
end
/app/mailers/reports_mailer.rb
def send_report(user, date_increment)
#user = user
#date_increment = date_increment
get_times(user)
mail :to => user.email, :subject=> "Report: #{#dates}"
end
--EDIT2--
So it looks like I need to use slanted single quotes (`) in order for this to work successfully. How do I force my app or MySQL to use these instead of double (") quotes?
I don't know why it does this, but I do know that if you're referencing column names in MYSQL, you need to use ``, whereas values / data should be wrapped in "", like this:
SELECT `users`.* FROM `users` WHERE `users`.`id` = "87" LIMIT 1
I learnt this the hard way back in the day when I was learning how to do simple MYSQL queries
Here's some documentation from MYSQL's site for you:
The identifier quote character is the backtick (“`”):
mysql> SELECT * FROM `select` WHERE `select`.id > 100;
Identifier quote characters can be included within an identifier if
you quote the identifier. If the character to be included within the
identifier is the same as that used to quote the identifier itself,
then you need to double the character. The following statement creates
a table named a`b that contains a column named c"d:
mysql> CREATE TABLE `a``b` (`c"d` INT);
Is there any reason you couldn't put some of your sql statement directly into your code like:
User.where("`report_daily`=1").find_each do |user|
After further inspection, and working with my hosting company, its turns out that my query is timing out on their server. Thanks to all that responded.
Since you are not using any literals, the format of the generated SQL statements should be determined by the underlying adapter. Perhaps you have a different mysql adapter installed or configured on each machine. Check the installed version. For example:
bundle show mysql
and also check the adapter configuration for your project in database.yml. For example:
adapter: mysql
A comparison of the results of these checks between each machine should tell you if you are using different adapters on the two machines.

Rails 3 MySQL 2 reports an error in what looks to be valid SQL syntax

I am trying to use the following bit of code to help in seeding my database. I need to add data continually over development and do not want to have to completely reseed data every time I add something new to the seeds.rb file. So I added the following function to insert the data if it doesn't already exist.
def AddSetting(group, name, value, desc)
Admin::Setting.create({group: group, name: name, value: value, description: desc}) unless Admin::Setting.find_by_sql("SELECT * FROM admin_settings WHERE group = '#{group}' AND name = '#{name}';").exists?
end
AddSetting('google', 'analytics_id', '', 'The ID of your Google Analytics account.')
AddSetting('general', 'page_title', '', '')
AddSetting('general', 'tag_line', '', '')
This function is included in the db/seeds.rb file. Is this the right way to do this?
However I am getting the following error when I try to run it through rake.
rake aborted!
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 'group = 'google' AND name = 'analytics_id'' at line 1: SELECT * FROM admin_settings WHERE group = 'google' AND name = 'analytics_id';
Tasks: TOP => db:seed
(See full trace by running task with --trace)
Process finished with exit code 1
What is confusing me is that I am generating correct SQL as far as I can tell. In fact my code generates the SQL and I pass that to the find_by_sql function for the model, Rails itself can't be changing the SQL, or is it?
SELECT * FROM admin_settings WHERE group = 'google' AND name = 'analytics_id';
I've written a lot of SQL over the years and I've looked through similar questions here. Maybe I've missed something, but I cannot see it.
"group" is a keyword so you can't use it as-is as an identifier, you have to quote it with backticks (for MySQL at least):
SELECT *
FROM admin_settings
WHERE `group` = 'google'
AND name = 'analytics_id'
Any SQL that Rails/ActiveRecord generates will use the quoted version of the column name so I'd guess that you're generating some SQL (or just a snippet of SQL for the WHERE clause) and neglecting to quote the column names.
I'd recommend against using group as a column name, use something else so that you don't have to worry about sprinkling backticks all over the place in your code.
group is an invalid field name if left unquoted, as it is a SQL keyword. To fix, surround it with backticks in your find_by_sql query, so your DB doesn't attempt to interpret it as the GROUP keyword.