MySQL vs SQL Commands - mysql

As far as I can gather, there are commands which are native to SQL such as SELECT and DELETE, and there are commands which are part of MySQL but not native to SQL such as use and describe. Have I got that right?
In this link the difference seems to be implied by having the MySQL commands in lower case. Is there a resource which shows which commands belong to which group i.e. native SQL vs MySQL-specific?

SQL is a language standard. Defined by organisations like ISO, ANSI, DIN.
Each SQL database system provides SQL, but with different scope and syntax. So you can learn the standard, but than you have to look for the distinctions. Or you directly learn a syntax of a specific database system. It depends on your purposes.
By the way the commands themself are case-insensitive. So it is indifferent if you write "select" or "SELECT". I prefer lower case because it is easy to write. Other prefer upper case because it is easy to read. In many projects the convention is upper case.

Related

Are the escape functions in the Node.js mysql package sufficient enough to securely query a mysql database (without the use of prepared statements)?

According to Node.js' mysql package documentation:
In order to avoid SQL Injection attacks, you should always escape any user provided data before using it inside a SQL query. You can do so using the mysql.escape(), connection.escape() or pool.escape() methods.
I cannot find any documentation / reference to using prepared statements with mysql, except for in a reference to using '?' characters. It states the following:
Alternatively, you can use ? characters as placeholders for values you would like to have escaped...
This looks similar to prepared statements in MySQL, however it really
just uses the same connection.escape() method internally.
From my experience with talking to other developers, the general consensus in the developer community is that prepared statements are the ONLY safe way to perform mysql queries from Node.js however, as you can see with the mysql package, there is no obvious support for prepared statements. However, it is indicated that their method for avoiding SQL injection is via the usage of the escape functions.
My Question:
Are the escape functions in the mysql package sufficient enough to securely query a mysql database (without the use of prepared statements)?
Escaping is actually just as safe as using parameterized queries, if you do it consistently.
But it's recommended to use parameters because it makes your code simpler. Therefore developers are probably more likely to do it.
If the Node.js library makes it just as convenient as parameters, but implements it internally by modifying query strings, replacing the ? marks with the parameter values, then you're good.
For what it's worth, Python's MySQL driver does this too, and also PHP's PDO extension when the "emulate prepares" option is in effect. As long as those libraries are well-tested, it should be safe.
FWIW, both escaping and parameters is limited in SQL injection prevention, because in both cases, you can only protect values that you would combine with your SQL query. You cannot protect identifiers (like table names, or column names), or SQL keywords, or expressions, etc. In these cases, just be careful that you have vetted any dynamic content before combining it with your SQL query.
See also:
Preventing SQL injection in Node.js
Difference between real_escape_string and prepare()?

Can I use either SQL, MySQL or SQLite to read a SQL database?

I'm not very versed on databases, so thismight sound wrong to some of you: Can I use SQL, MySQL and/or SQLite to read the same database? If so, are there commands or instructions I should keep an eye on to not make a mess on the tables?
Thanks in advance!
sql is a language. sqlite and mysql are database engines.
Both SQLite and MySQL (as far as any SQL engines) allows SQL language to manipulate database content (with some engine specific ).
So you may use SQL to read a MySQL or SQLite database. But be aware that SQL use in each is engine dependent. For instance, in SQLite you may use shell application, c wrapper, ... For MySQL you may use php wrapper, ...

How do I quote a reserved word in SQL so it works across all the common database systems?

Say I have a table call ‘users’ with a column ‘order’ and I wish my application code to work across all the database systems out there.
Assume that it is impractical to change the database schema. Even if the schema was change, one of the main database engine will come up with yet another reserved word, so stopping the app working when a database engine is updated.
I would rather not have to process the SQL strings to convert them into the correct form for each database.
'How to find if a column name is a reserved keyword across various databases' partly overlaps with this question.
('Syntax error due to using a reserved word as a table or column name in MySQL' is the reference question for MySQL.
)
You have to test on everything you are going to support, so "all the database systems out there" is not in realty an option.
To be more realistic, you can decide which DBMS you want to support, and write a subset of SQL which they are all happy with, and test them with automated tests.
For example, you might consider:
MySQL
Postgres
MS SQL Server
Oracle
I believe these all support ANSI double-quotes for quoting names, so if you quote all names all the time then you have one less thing to worry about.

Oracle to PostgreSQL query converter Possible?

I am thinking to write a converter that takes any oracle query and return Postgresql format of the query assuming table and columns are same.
what I do right now I do timely conversions so I have basic understanding about both and want some expert advice that is it easily possible or not?
Try to use "commercial" version of PostgreSQL - EnterpriseDB. It has an compatibility layer for Oracle.
If you're about to write the "convector" by your own: look at this github project: https://github.com/porcelli/plsql-parser. It's open-source parser for Oracle's SQL dialect. I have to warn you, even if you have AST for Oracle query it is still a lot of to do to convert AST into other SQL dialect. You will also need plenty of sample queries for testing. You can find some sample queries in this project's tests folder.
Also similar project was implemented for MySQL, but I can not find it's homepage now.
Part of the solution is to make available in PostgreSQL the functions available in Oracle. You can have a look at http://orafce.projects.pgfoundry.org/
"The goal of this project is to implemente some functions from Oracle database. Some date functions (next_day, last_day, trunc, round, ...), string functions and some modules (DBMS_ALERT, DBMS_OUTPUT, UTL_FILE, DBMS_PIPE, ...) are implemented now. Funcionality was verified on Oracle 10g and module is useful for production work."
Not possible for every query. They each have syntax and functionality that the other does not -- for example, the MODEL clause in Oracle, or PostgreSQL's special form of "SELECT DISTINCT ON".
Mostly, Oracle has functionality that PostgreSQL doesn't: http://docs.oracle.com/cd/B28359_01/server.111/b28286/statements_10002.htm

switching from MySQL to PostgreSQL for Ruby on Rails for the sake of Heroku

I'm trying to push a brand new Ruby on Rails app to Heroku. Currently, it sits on MySQL. It looks like Heroku doesn't really support MySQL and so we are considering using PostgreSQL, which they DO support.
How difficult should I expect this to be? What do I need to do to make this happen?
Again, please note that my DB as of right now (both development & production) are completely empty.
Common issues:
GROUP BY behavior. PostgreSQL has a rather strict GROUP BY. If you use a GROUP BY clause, then every column in your SELECT must either appear in your GROUP BY or be used in an aggregate function.
Data truncation. MySQL will quietly truncate a long string to fit inside a char(n) column unless your server is in strict mode, PostgreSQL will complain and make you truncate your string yourself.
Quoting is different, MySQL uses backticks for quoting identifiers whereas PostgreSQL uses double quotes.
LIKE is case insensitive in MySQL but not in PostgreSQL. This leads many MySQL users to use LIKE as a case insensitive string equality operator.
(1) will be an issue if you use AR's group method in any of your queries or GROUP BY in any raw SQL. Do some searching for column "X" must appear in the GROUP BY clause or be used in an aggregate function and you'll see some examples and common solutions.
(2) will be an issue if you use string columns anywhere in your application and your models aren't properly validating the length of all incoming string values. Note that creating a string column in Rails without specifying a limit actually creates a varchar(255) column so there actually is an implicit :limit => 255 even though you didn't specify one. An alternative is to use t.text for your strings instead of t.string; this will let you work with arbitrarily large strings without penalty (for PostgreSQL at least). As Erwin notes below (and every other chance he gets), varchar(n) is a bit of an anachronism in the PostgreSQL world.
(3) shouldn't be a problem unless you have raw SQL in your code.
(4) will be an issue if you're using LIKE anywhere in your application. You can fix this one by changing a like b to lower(a) like lower(b) (or upper(a) like upper(b) if you like to shout) or a ilike b but be aware that PostgreSQL's ILIKE is non-standard.
There are other differences that can cause trouble but those seem like the most common issues.
You'll have to review a few things to feel safe:
group calls.
Raw SQL (including any snippets in where calls).
String length validations in your models.
All uses of LIKE.
If you have no data to migrate, it should be as simple as telling your Gemfile to use the pg gem instead, running bundle install, and updating your database.yml file to point to your PostgreSQL databases. Then just run your migrations (rake db:migrate) and everything should work great.
Don't feel you have to migrate to Postgres - there are several MySQL Addon providers available on Heroku - http://addons.heroku.com/cleardb is the one I've had the most success with.
It should be simplicity itself: port the DDL from MySQL to PostgreSQL.
Does Heroku have any schema creation scripts? I'd depend on those if they were available.
MySQL and PostgreSQL are different (e.g. identity type for MySQL, sequences for PostgreSQL). But the port shouldn't be too hard. How many tables? Tens are doable.