Cheapest SQL Statement possible / Are there Client-Side SQL Statements? - mysql

Questions
What is/are the most cheapest SQL-Statment(s) (in terms of Processing Overhead/CPU Cycles).
Are there (this will most likely be DB-Client specific) any Statments that are evaluated directly by the client and even do not go to the database server?
The result doesn't matter, if an empty statement (which produces an SQL Error) is the cheapest OK, then this is good too. But I am more interested in non Error Responses.
Background:
I have an application that queries a lot of data from the DB. However I do not require this data. Sadly, I have no possibility to skip this query. But I have the possibility to change the SQL Query itself. So I am trying to find the cheapst SQL Statement to use, ideally it should not even go to the SQL Server and the SQL-Client Library should answer it. I will be using MySQL.
UPDATES (on comments):
Yes, it can be a No-Operation. It must be something I can pass as a regular SQL String to the mysql client library. Whatever that string could be, is the question. The goal is, that this Query then somehowreturns nothing, using the least Resources on the SQL Server as possible. But in idealcase the client itself will realize that this query doesnt even have to go to the server, like a version Check of the client library (OK I know this is no standard SQL then but maybe there is something I do not know about, a statement that will be "short circuited/answered" on the client itself).
Thanks very much!

DO 0
DO executes the expressions but does not return any results. In most respects, DO is shorthand for SELECT expr, ..., but has the advantage that it is slightly faster when you do not care about the result.

Related

Can mojolicious output the prepared sql query?

Perl Mojolicious use query with placeholder to prevent SQL injection. But the problem is, sometimes I want to see what's the query look like.
Is there a way to print the query with all placeholders replaced with the real values?
I know I can do a replace by myself. But I have to do it every time I want to debug the SQL. It's so cumbersome. If mojolicious has a way like $c->mysql->output_last_sql(), it'll be amazing.
my $sql=q|
SELECT
count(*) cnt
FROM
my_table
WHERE
id= ?
|;
# I know I can do below by myself
print q1|
SELECT
count(*) cnt
FROM
my_table
WHERE
id= $c->param('id')
|;
my $query=$c->mysql->db->query($sql, $c->param('id'));
# how can I print the real SQL with all placeholders replaced?
print $query->hash()->{cnt};
I checked the document of Mojolicious but didn't find anything useful.
https://docs.mojolicious.org/Mojo/Pg/Database
The advantage of query parameters is that they are not simply string-replacements into the SQL query. If they were, they would still cause a risk of SQL injection. The way parameters work is that they are never replaced in your query until after the query is prepared. Parsing occurs during the prepare step, so if parameter values are not combined with the query until after parsing, then there's no way for the values to cause mischief with the SQL syntax.
That means you can't get the SQL combined with its parameters in the client.
The only workaround is to use the query log on the MySQL Server. I give an example here: Getting raw SQL query string from PDO prepared statements. That's about PHP, not Perl, but it works the same regardless of which language you use.
(With exceptions only for client connectors that create fake prepared statements, and actually do interpolate parameters into the SQL string, then send it to the MySQL Server. For example, Python's connector does this by default, for example, but you can optionally make even Python use true prepared statements.)

Handling SQL request with parameters and avoiding SQL injection

This question is quite open ended. Maybe it doesn't belong here, so sorry in advance if that's the case.
I'm using SQL in a real project for the first time, and I'm having some issues. I'm also using php and javascript.
In the web app I'm currently writing, i do a lot of SQL query to my MySQL database. Each one of these query do a different thing, on different tables, etc.
At the moment, I'm doing the following : each time i do a query in the client side code, I'm passing a parameter I defined myself to the server.
On the server, I wrote a switch on this parameter. So it looks like this :
if (parameter == 1)
/*Query 1*/
else if (parameter == 2)
/*Query 2*/
etc.
It's not very convenient. However, if i use a function writing a SQL query by taking parameters from the client, it would be subject to SQL injection.
So to sum it up : how do i create a SQL query in the most "modular" way possible and still avoid SQL injection ?
I already know about prepared statement, but if i get it right, i can't write a full SQL query with only prepared statement.

mySQL: Stored procedures are more secure than queries?

I have a website using mySQL database and I want to do common tasks like add users, modify their info, etc. I can do it perfectly with regular queries. Im using prepared statements to increment security.
Should I use stored procedures to increment the security or the results will be the same? I though that may be using stored procedures I can restrict the direct interaction that a possible attacker could have with the real query. I'm wrong?
I guess it would depend on what language youre using. Using a prepared statement with a sql string that contains all of the sql to be executed, or using a prepared statement with a sql string that executes a stored procedure are going to be about equivalent in most languages. The language should take care of the security around the prepared statement. C# for example will validate the input, so sql injection vulnerabilities are greatly reduced unless your prepared statement is written so poorly that feeding it bad (but expected, ie, 1 vs 0) variables will dramatically change the result set. Other languages may not provide the same level of validation though, so there may be an advantage depending on exactly what your stored proc looks like.
Using a stored procedure is better for maintainability, but there are not many scenarios where its going to provide any sort of change in security level, assuming the program is properly designed to begin with. The only example i can think of off the top of my head would be a stored procedure that takes raw sql strings from user input, and then executes that sql against the db. This is actually less secure than using a prepared statement unless you went to great lengths to validate the acceptable input, in which case you better have a really good reason for using such a stored proc in the first place.
Basically, what I'm saying boils down to the fact that you're going to need to read the documentation for your language about prepared statements, and determine what vulnerabilities, if any, using prepared statements may have, and whether or not those can be eliminated in your specific scenario by switching to a prepared statement that calls out a stored procedure instead of executing a sql query directly.
The results would be the same (assuming that you set your stored procedure up right).
there appears to be a pretty good write up on it here. Though I would never suggest you try to escape user input yourself. (They mention this as option 3)

Query to detect MySQL

I'm fixing a bug in a proprietary piece of software, where I have some kind of JDBC Connection (pooled or not, wrapped or not,...). I need to detect if it is a MySQL connection or not. All I can use is an SQL query.
What would be an SQL query that succeeds on MySQL each and every time (MySQL 5 and higher is enough) and fails (Syntax error) on every other database?
The preferred way, using JDBC Metadata...
If you have access to a JDBC Connection, you can retrieve the vendor of database server fairly easily without going through an SQL query.
Simply check the connection metadata:
string dbType = connection.getMetaData().getDatabaseProductName();
This will should give you a string that beings with "MySQL" if the database is in fact MySQL (the string can differ between the community and enterprise edition).
If your bug is caused by the lack of support for one particular type of statement which so happens that MySQL doesn't support, you really should in fact rely on the appropriate metadata method to verify support for that particular feature instead of hard coding a workaround specifically for MySQL. There are other MySQL-like databases out there (MariaDB for example).
If you really must pass through an SQL query, you can retrieve the same string using this query:
SELECT ##version_comment as 'DatabaseProductName';
However, the preferred way is by reading the DatabaseMetaData object JDBC provides you with.
Assuming your interesting preconditions (which other answers try to work around):
Do something like this:
SELECT SQL_NO_CACHE 1;
This gives you a single value in MySQL, and fails in other platforms because SQL_NO_CACHE is a MySQL instruction, not a column.
Alternatively, if your connection has the appropriate privileges:
SELECT * FROM mysql.db;
This is an information table in a database specific to MySQL, so will fail on other platforms.
The other ways are better, but if you really are constrained as you say in your question, this is the way to do it.
MySql may be the only db engine that uses backticks. That means something like this should work.
SELECT count(*)
FROM `INFORMATION_SCHEMA.CHARACTER_SETS`
where 1=3
I might not have the backticks in the right spot. Maybe they go like this:
FROM `INFORMATION_SCHEMA`.`CHARACTER_SETS`
Someone who works with MySql would know.

Can I obfuscate the SQL code in MySQL?

I'm trying to find some way to obfuscate SQL code in MySQL.
In the Oracle databases exists the "wrap" funcionality, but I didn't found some similar. Some ideas?
The final goal is that the client has some difficuties to understand the code.
I think MySQL do not have the ability to obfuscate the code. You can encapsulate the whole SQL query code by creating a STORED PROCEDURE, although not encapsulated but at least your whole SQL query is not shown when used inside your code (PHP, .Net, and the like...).
MySQL does not have any obfuscation abilities - you could write some code that would be confusing to read by having some other table with defined values that you could use IF statements against to make your code difficult to read...
SELECT co1, co2, IF(3 > 18, co3, '') AS co3 FROM table INNER JOIN...
etc... or using COUNTs as parameters in conditional statements is as best as you're going to get (obviously performance may become an issue depending on how "obfuscated").