2 Mysql queries in 1 variable, help? - php

$qry1 = "DELETE FROM
si_topics
WHERE
topic_id = '". $_GET['topic'] ."'
DELETE FROM
si_posts
WHERE
topic_id = '". $_GET['topic'] ."'";
$mysqlqry1 = mysql_query($qry1);
if($mysqlqry1){
echo 'Topic deleted from database!';
} else {
echo 'Mysql query failed!';
}
This gives the message Mysql query failed!, why?
Greetings

You are missing a semicolon between your two delete statements.
Also, multiple queries are not supported in mysql_query.
From the documentation:
mysql_query() sends a unique query (multiple queries are not supported) to the currently active database on the server that's associated with the specified link_identifier.`

You can not run multiple queries in mysql_query() function in once.
Try mysqli::multi_query instead to run multiple queries. queries can be separated by ;

Quoting from the manual (my emphasis)
mysql_query() sends a unique query (multiple queries are not supported)
If you want to execute several SQL statements in a single query, you need to use mysqli and multi-query, and each statement needs to be separated by a semi-colon (;)

Because:
you're sending one query with invalid syntax, and
even if you'd added the semicolon between queries (how else is the MySQL server supposed to know where your second query starts?!?), PHP's old library doesn't support that here.
Use mysqli.multi_query() instead.
You should also either use prepared statements or at the very least sanitise your inputs, as your code has a huge SQL Injection vulnerability (how are people still writing PHP like this?!? what are they teaching in these "schools"?! aghh!)

PHP does not allow running 2 queries in one go.
You need to split your queries in 2 variables and run them one by one.
http://php.net/manual/en/function.mysql-query.php
The documentation explains:
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier.
The standard MySQL separator semicolon ( ; ) will not work here.

If you wish to specify multiple delete conditions across several tables, then you can use JOIN syntax for the DELETE statement, however this might be inefficient - but that way, the query will fit within mysql_query();
Someone already mentioned mysqli and multi_query function, thumbs up for that :)
On the other hand, your code is extremely prone to SQL injection attacks, always clean your $_POST and $_GET input before using it in the query directly!

Add mysql_error ($link) after 'echo 'Mysql query failed!';' line
That will explain the problem.

Related

Can you omit PDO prepare if there's no placeholder/dynamic data in a query?

I'm working on an application at the moment that uses PDO with a MySQL database.
I'm seeing some queries, which are just very simple SELECT statements, e.g.
SELECT * FROM table ORDER BY name ASC
The code does not use prepare, for example:
$sql = "SELECT * FROM " . $this->table . " ORDER BY name ASC";
$stmt = $this->db->query($sql);
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $results;
Is it ok to do this, i.e. without using prepare, if there's no placeholders in the query?
The reason I've asked this is because according to the documentation it says
The SQL statement can contain zero or more named (:name) or question mark (?) parameter markers
which makes me wonder why you'd use this in the case of having no (zero) parameter markers?
Yes, because the use of prepared statements have 2 main causes:
Enhance running the same query with different parameters.
Prevent sql injection by separating sql code from the parameters.
Since you have no parameters that could be handled by a prepared statement (table names cannot be a parameter), you do not gain anything by pushing the query through as a prepared statement.
You still need to make sure that whatever is returned by $this->table will not cause any issues with the generated sql code.
Of course you can omit prepare if there is no dynamic data in your query.
But prepared statements have more advantages than only securing your queries.
According to http://php.net/manual/en/pdo.prepared-statements.php a second advantage is, that statements can be prepared once and executed multiple times.
The query only needs to be parsed (or prepared) once, but can be executed multiple times with the same or different parameters. When the query is prepared, the database will analyze, compile and optimize its plan for executing the query. For complex queries this process can take up enough time that it will noticeably slow down an application if there is a need to repeat the same query many times with different parameters. By using a prepared statement the application avoids repeating the analyze/compile/optimize cycle. This means that prepared statements use fewer resources and thus run faster.
Nevertheless, if you run your query only once and there is no dynamic data inside your query, omitting prepare is also fine.
In reality, you have to run such a query extremely seldom. A few tables with configuration-like options may be.
In all other cases at least LIMIT clause is obligatory.
So the question is rather a theoretical one.

How to execute two sql queries in php?

I am trying to execute this code in a php page to store some data on my database.
The thing is that I want to Insert data, but due to a foreign key constraint it is impossible. So, in my php code I want to execute two sql queries. The first one to disable foreign key checks and the second one to insert the data.
When I try it in phpmyadmin it works. But manually. I would like to put it on php code.
This is my code. The parameter $conexion is the one that executes my sql queries.
Any ideas?
$sql = "SET foreign_key_checks=0";
$sql. = "INSERT INTO routes (title, distance, subtitle) VALUES ('".$_POST['title']."','".$_POST['distance']."', '".$_POST['subtitle']."');";
$conexion->multi_query($sql);
Try to avoid using multi_query. Sending a small query to the MySQL server doesn't really affect performance and does prevent kind of limit the effect of something like SQL injection.
In your case there's no need for multi_query. If you send two queries in a script, both go over on the same connection. The SET query affect the current connection.
// Protect against SQL injection
$title = $conexion->escape_string($_POST['title']);
$distance = $conexion->escape_string($_POST['distance']);
$subtitle = $conexion->escape_string($_POST['subtitle']);
// Execute queries
$conexion->query("SET forgeign_key_checks=0");
$conexion->query("INSERT INTO routes (title, distance, subtitle) VALUES ('$tittle', '$distance', '$subtitle')");
Apart from the comment above, you need a semi-colon between your sql statements
multi_query - Executes one or multiple queries which are concatenated by a semicolon.

find type of sql statement using php and no Regex

I am wondering
if we can know..
what type of query is executed in php script.
DML or DDL statement
Can know that.. using php..
with out Regex
Below is the query i executed
$queryOne = "SELECT * FROM employees";
// using php script
$queryOne is DML
$queryTwo = "DROP table employees";
//using php script
$queryTwo is DDL
Classically, the DML statements are:
SELECT
INSERT
DELETE
UPDATE
MERGE (newcomer on the block)
Anything else is DDL - according to some sets of definitions.
Some of the 'other statements' are more like 'session control' statements; not really DML, not really DDL.
If you wish to detect these statements, you can either prepare (and describe) the statement and look at the returned information to diagnose whether it is one of the DML statements listed above, or you can scan for these keywords as the first non-comment words in the statement. This covers the vast majority of practical cases. What you do if you have a single string with multiple statements (possibly of different types) in them is a decision you'll have to make on your own. Not all DBMS allow that anyway.
or use regex.

Is there any way to send more than one postgresql sql prepared statement in one call in php?

Is there any way to execute more sql prepared statements at once? Or at least use something to achieve this result, can it be emulated with transactions?
pg_send_query can execute more statements (from php docs "The SQL statement or statements to be executed.")
but
pg_send_execute and pg_send_prepare can work only with one statement.
The query parameter has the following description
"The parameterized SQL statement. Must contain only a single statement. (multiple statements separated by semi-colons are not allowed.) If any parameters are used, they are referred to as $1, $2, etc."
from http://www.php.net/manual/en/function.pg-send-prepare.php
Is there any way to send more statements at once to make less roundtrips between php and postgresql like the pg_send_query does?
I don't want to use pg_send_query because without parameter binding I can have sql injection vulnerabilities in my code.
The round trips to the DB server shouldn't be your bottleneck as long as you are (a) using persistent connections (either directly or via a pool) and (b) aren't suffering from the "n+1 selects" problem.
New connections have an order of magnitude overhead which slows things down if done on every query. The n+1 problem results in generating far more trips than is really needed if the application retrieved (or acted upon) sets of related rows rather than doing all operations one at a time.
See: What is the n+1 selects problem?
Separate your queries by semicolon:
UPDATE customers SET last_name = 'foo' WHERE id = 1;UPDATE customers SET last_name = 'bar' WHERE id = 2;
Edit:
Okay you cannot do this on the call side:
The parameterized SQL statement. Must contain only a single statement. (multiple statements separated by semi-colons are not allowed.)
Another way would be to call a stored procedure with this method and this SP issues multiple statements.

Select more tables after FROM statement?

this is part of a security audition, so there is no way to "change" the query.
Basically, what I found is a flaw that allows statement manipulation, so basically it goes like:
$query = "DELETE FROM `products` WHERE `products`.`whatever` = $variable";
This is PHP, so as far as I know there is no way to execute multiple queries. Using this SQL Injection, I was able to "clear" this table by running "0 OR 1=1#".
This works just fine, but it doesn't allow me to choose more tables to delete from.
This is, in pseudocode what I want to do:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1, FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
Is this plausible anyhow?
If this isn't reliable, is there any other way I could use this?
You can't have multiple FROM clauses for the same DELETE statement, so you can't go about it exactly how you'd want to. If the MySQL db had 'allow multiple queries per statement' turned on, you could try to terminate the one DELETE query and then tack on another to the end, so that it'd look like this:
DELETE FROM `products` WHERE `products`.`whatever` = **0 OR 1=1; DELETE FROM `othertable` WHERE `othertable`.`othercolumn` = 0 OR 1=1**
But that's about it.
Perhaps I don't fully understand the question, but what I take away is that you're building a SQL command as a string and running that string directly against a MySQL database.
You can separate multiple commands using the command separator (usually ';'), so you could run pretty much any command you want as this comic aptly illustrates.
If your database configuration supports multiple commands (or might in the future if someone changes today's setting), you want to ensure you don't have a command separator as part of the input. See this article for advice on sanitizing your input to prevent this type of attack.
As you stated, multiple queries are not supported by the normal MySQL driver module. From the manual for mysql_query:
mysql_query() sends a unique query
(multiple queries are not supported)
to the currently active database on
the server that's associated with the
specified link_identifier .
Unfortunately for your injection efforts, DELETE syntax only supports multiple table deletes by specifying them in the FROM clause. Your injected variable is part of the WHERE, so the most damage you can do is to the single specified table.
Contrary to popular belief, you can actually run multiple MySQL statements from PHP, you just have to be using a different database driver module such as MySQLi. See MySQLi::multi_query().

Categories