normal MYSQL does not work asking for PDO - php

I have been trying to run my stored procedure using mysql unsuccessful for quite sometime. whenever I use the code below
$link_id = DbConnection::getInstance('mycon')->connectMysql();
$table_count = mysql_query("SELECT TABLE_NAME FROM information_schema.tables WHERE table_schema = 'mycon' AND table_name LIKE 'table_%' ")
while($row = mysql_fetch_array($table_count)){
$table = $row["TABLE_NAME"];
$excute = mysql_query("dummy_2('$table')") or die(mysql_error());
$result = mysql_fetch_assoc($excute);
var_dump($result);
}
it gives an error saying
Commands out of sync; you can't run this command now
so when I searched the internet, it said that I need to use MYSQL PDO.. Therefore can anyone convert my above statement to mysql pdo.. since i got no clue about PDO whatsoever

When you query something from the MySQL database the result is presented as a result set. Actually some queries might have multiple result sets associated. But there can be only one active list of results sets per connection. I.e. you, your script somehow has to close all currently active result sets before you can issue another query.
If e.g. your stored function uses multiple SELECTs the function has multiple result sets and you have to iterate/close/drop them all.
http://dev.mysql.com/doc/refman/5.1/en/stored-routines-syntax.html:
MySQL supports a very useful extension that enables the use of regular SELECT statements (that is, without using cursors or local variables) inside a stored procedure. The result set of such a query is simply sent directly to the client. Multiple SELECT statements generate multiple result sets, so the client must use a MySQL client library that supports multiple result sets.
The old, deprecated mysql_* functions do not support multiple result sets - you simply can't iterate/drop them.
The mysqli_* extension does: see http://docs.php.net/mysqli.next-result
And so does PDO: see http://docs.php.net/pdostatement.nextrowset.php

Related

PDOStatement::nextRowSet() is broken in MySQL 5.6.16 on Windows

This question without an accepted answer raises a catastrophic problem with MySQL that I am experiencing on MySQL version 5.6.16 on Windows in a modified form.
The problem is easily reproducible: I include it here (copied from the above-linked question, but with changes applicable to my code):
$pdo = /* connection stuff here */
$sql = "call test();"; // call stored procedure - see below
$statement = $connection->query($sql);
do {
$rowset = $statement->fetchAll(PDO::FETCH_ASSOC);
if($rowset) {
// Do stuff with $rowset
}
} while($statement->nextRowset());
Here is the definition of the stored procedure test:
DELIMITER $$
DROP PROCEDURE IF EXISTS `test`$$
CREATE PROCEDURE `test`()
BEGIN
SELECT 1; SELECT 2; SELECT 3; SELECT 4;
END$$
DELIMITER ;
The only difference between my code, and the above-linked code, is that I pack the SQL query into a stored procedure.
In my case, the while statement returns true four times, rather than three times (it should be just three times). After the fourth time, fetchAll(...) throws a SQLSTATE[HY000]: General error error.
Unfortunately, this problem is catastrophic. There is no other way with PDO to iterate to following rowsets other than using the nextRowSet() function. Therefore, I may revert to a previous version of MySQL in order to work around this issue.
I have found two links that seem to indicate this issue, listed here:
https://bugs.php.net/bug.php?id=67130 and
http://permalink.gmane.org/gmane.comp.php.devel/81518
I would appreciate a confirmation that this is, indeed, a bug with version 5.6.16 of MySQL on Windows. Even more, I would appreciate a workaround. Thanks.
I had same problem with PDO::nextRowset(), as it returns true even there are no more rowsets available, therefore when calling fetchAll(), it raises exception HY000. (tested on PHP 5.5.12 windows, Mysql 5.5.17 linux)
A workaround for this problem is to check number of columns with method PDO::columnCount() before fetching rowset. If it is non-zero, you have a valid rowset, and thus you could call PDO::fetchAll().
Even if PDO::nextRowset() reports true, columnCount() will report number of columns before moving to next rowset.
Example:
while ($objQuery->columnCount()) {
$tab[] = $objQuery->fetchAll(\PDO::FETCH_ASSOC);
$objQuery->nextRowset();
}
If the problem is being caused by multiple result sets, then maybe the best work around would be to find ways of avoiding multiple result sets in a single query.
For example, if the expected results are in the same format (which I expect they probably are because you intend to use the same code to deal with all of them) then you could potentially use UNION to compound the four queries together.
SELECT 1
UNION ALL
SELECT 2
UNION ALL
SELECT 3
UNION ALL
SELECT 4;
Failing that, you can execute a separate query for each SELECT and hand the result off to a function to do the processing.

Small MySQL bug

I am new to PHP and MySQL, and I am having a bit of bother with the SELECT query. I am having some issues with this PHP/SQL variable:
$dbPassword = mysql_query("SELECT UserData.Password FROM UserData WHERE UserData.EmailAddress = '.$loginEmail.'");
What would be the correct way to select a value from a row where the "EmailAddress" is the same as another value in an Apache MySQL server?
All help will be appreciated.
Note that $dbPassword would be a resultset object, not a scalar.
You'd need to "fetch" rows from the resulset.
An example is provided in the documentation http://www.php.net/manual/en/function.mysql-query.php
You also have an issue with PHP string concatenation.
If you did this in two separate steps, you could echo (or printf or vardump) the string containing your SQL statement, before you execute it.
Also note that including "unsafe" values in the SQL statement makes your code vulnerable to SQL injection. Little Bobby Tables
$sql = "SELECT UserData.Password FROM UserData WHERE UserData.EmailAddress = '"
. mysql_real_escape_string($loginEmail) . "'";
vardump($sql);
$res = mysql_query($sql);
(The vardump isn't required; it's just there for debugging, a way for us to see the contents of the string that is about to be sent to the database. (When we're debugging a problem, it helps us determine whether the problem is in the SQL text, or whether it's a problem in the database.
We'll want to test whether the call to mysql_query actually returned a resultset, or whether it returned an error. Once we've verified it's a valid resultset object, we can fetch rows from the resultset. (There's a variety of functions to perform that operation.)
Note: The red box in the documentation that says the mysql extension is deprecated. New code should use either the mysqli or PDO extension.

How many sql queries does this scenario make (PHP)?

Ok, so if I set into a variable an sql_query like so:
$query = mysql_query("..");
and call multiple mysql_result's like so:
mysql_result($query, 0);
mysql_result($query, 1);
mysql_result($query, 2);
How many queries will the page call to the server?
Only once? or three times?
When you execute mysql_query, It executes the sql and it keeps the result in an internal result structure. Next time when you call mysql_result, it fetches from that internal result.
For buffered query the reusult will be copying from MySQL server to PHP as soon as mysql_query is executed. For un-buffered query it'll be copied lazily.
So in both case Query executes only one time. But for un-buffered query it'll be fetched from MySQL server. every time you call mysql_result or mysq_fetch_*.Buffered and Unbuffered queries
You have given the answer yourself. If you are calling "query" function once, then it will only
execute once no matter how many times you parse its return value
$query = mysql_query("..");
When you run the above code then query gets executed and the returned resource is in $query variable. Then you can fetch data from it multiple times but query wont run again.
Here will be one query with database that's means Server. mysql_result() should not be mixed with calls to other functions that deal with the result set.
For more information you can visit : http://php.net/manual/en/function.mysql-result.php
Only *mysql_query* is executing against the mysql server. Only one query
mysql_result only fetches data from a mysql resource, it doesn't matter if you have previously gotten it from a query in code or managed to get it from another source.
From PHP 5.5.0 onwards this function is deprecated; the new way to perform this action would be to create a mysqli object and use over the functions mysqli::query and mysqli::fetch_field

MSSQL_query in PHP Returning Diffrent Results than SQL Native Sproc

Anyone ran into this one before?
I have a Stored Procedure in SQL with the following Parameters :
exec PaySummary 'DemoTest', 'DemoTest-Mohn-00038', '5/14/12', '5/27/12', 'manager', 'DemoTest-Boyd-00005'
And the following MSSQL Query in PHP running the exact same query.
private function dataTest(){
$strSQL = 'exec PaySummary \'DemoTest\', \'DemoTest-Mohn-00038\', \'5/14/12\', \'5/27/12\', \'manager\', \'DemoTest-Boyd-00005\'';
$a = mssql_query($strSQL);
echo $strSQL;
while($row=mssql_fetch_array($a)){
var_dump($row);
}
}
When run in SQL for this query I will get 3 results...
When run in PHP through SQL I get 2 Results...
Is there any run time settings (Set NoCOUNT on) that you must set on a SQL Stored Procedure to ensure accuracy of the output of results? Or is there a known issue with passing date parameters that would impact the results of a date driven stored procedure?
Microsoft-IIS/5.0 / PHP/5.2.5 / SQL Server 2008 R2 (Where the stored procedure is executed).
For anyone in this same situation... It is caused by the NULL_CONCAT_NULL (or whatever) option in SQL. This one flag can make a stored procedure run a little bit differently depending on how you use concat etc. A good way to solve this problem is via an ISNULL around a lot of your items which seemed to get rid of the issue of getting different results.
Further another option if you do not want to fix your sprocs is to check the path that sql is going through (TCP/IP etc). I noticed when watching the audits that some settings were wildly different depending on the port that sql was running through.

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