0

Enviro: MySQL, PHP 5.5

I have a situation where I need to return a random result from the Database. I have tried two methods of doing this. One which returns an array of results and I randomly pick one using the array_rand($results) and the other is adding order by rand() limit1;

When I returned a list of results the execution time was recorded reported from the MySQL console like so:

602 rows in set (0.05 sec)
Query OK, 0 rows affected (49.37 sec)

This is not good. So I choose the other method which reported:

1 row in set (0.05 sec)
Query OK, 0 rows affected (0.36 sec)    

The issue became when run this query for a second time, I am passing in the arg that records the previous record retrieved so I avoid duplicates

Here is my routine:

CREATE PROCEDURE `getRandomRecord`(
    IN _args varchar(100)
)
BEGIN
    SET @query = CONCAT('SELECT C.*, B.*
    FROM C
    LEFT JOIN B
    ON B.id = c.Bid
    where (C.Type=27 || C.Type=28 || C.Type=29) 
    and C.EndDate>CURRENT_TIMESTAMP() ',_args,' order by rand() limit 1;');

    PREPARE stmt FROM @query;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
END//

This executes the first time without an issue, but on the PHP side when I run this a second time the call fails.

The args are being recorded like so:

$args= !empty($args) ? $args : '';
//args is empty first time
$dbHandler = new RandomRecordDatabase();
$results = $dbHandler->getRandomRecord($args);
//Do Stuff HERE
$args .= ' AND C.id!='.$results['C.id'];
$dealer_results = $dbHandler->getRandomRecord($args);

The function is like this:

public function getRandomRecord($args){
    try
    {
        $procedure = "Call getRandomRecord(?)";
        $statement = $this -> _dbh -> prepare($procedure);
        $statement -> bindParam(1, $args);
        $statement -> execute();
        $results = $statement -> fetchAll(PDO::FETCH_ASSOC);
        return $results[0];
    }
    catch(PDOException $e)
    {
            echo $e -> getMessage();
    }
}

On the second call to this method, I get the following PDOException:

Warning: PDOStatement::execute(): SQLSTATE[42000]: Syntax error or access violation: 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 '"387 order by rand() limit 1'

Which references the line $statement -> execute();

How can I fix this error? Thank you!

UPDATE(SOLUTION):

I should of reviewed the Output of args more closely and I would of seen the error: echo $args;

In one instance I noted a mix case: " AND C.id=123 AND AND C.id=456 and C.id="111" AND C.id=789.

I modified the one case which I never noted located in a different script. This now fixes the issue.

mcv
  • 1,380
  • 3
  • 16
  • 41
  • 1
    you know what? just replace this line **$args .= ' AND C.id!='.intval($results['C.id']);** – Alex Apr 10 '15 at 14:05
  • @Alex I tried and the error remains the same as without the **intval()** – mcv Apr 10 '15 at 14:14
  • 1
    the same **se near '"387** ?? are you sure? and add param type by the way `$statement -> bindParam(1, $args,PDO::PARAM_STR);` – Alex Apr 10 '15 at 14:24
  • 1
    can you enable general query log for mysql and copy the executed queries here. It's strange, that the " is before a number which seems to be the ID in your argument http://stackoverflow.com/questions/650238/how-to-show-the-last-queries-executed-on-mysql – jenschude Apr 10 '15 at 15:00
  • Working with old PHP scripts. I echoed the args and noted that there was an instance of **C.id="1111"** which got initialized inside another script. So there was a mix case of **AND C.id=123 AND C.id=234 and C.id="111" AND C.id=456** This project is ancient and I'm trying to revamp it while maintain it's current state. – mcv Apr 10 '15 at 15:58

1 Answers1

1

You are missing the second quote after your variable, that is what the error message is saying. Quotes around integers are not required, nor advised, in sql.

I can not see where you are introducing that erroneous quote since you have not posted all the relevent code.

David Soussan
  • 2,698
  • 1
  • 16
  • 19
  • This is how I am creating my arg: **$args .= ' AND C.id!='.$results['C.id'];** You are right I did modify it, and each time I see a typo, I have edited it. I am reviewing it but could you provide a snippet example in your response so I might understand better. :) – mcv Apr 10 '15 at 14:00