0

環境: MySQL、PHP 5.5

データベースからランダムな結果を返す必要がある状況があります。私はこれを行う2つの方法を試しました。1 つは結果の配列を返すもので、 を使用して 1 つをランダムに選択しarray_rand($results)、もう 1 つは を追加していorder by rand() limit1ます。

結果のリストを返すと、次のように MySQL コンソールから報告された実行時間が記録されました。

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

これは良くない。だから私は報告した他の方法を選択します:

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

このクエリを 2 回目に実行すると問題が発生しました。以前に取得したレコードを記録する引数を渡しているため、重複を回避できます。

これが私のルーチンです:

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//

これは問題なく初めて実行されますが、これを 2 回目に実行すると PHP 側で呼び出しが失敗します。

引数は次のように記録されています。

$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);

関数は次のようになります。

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();
    }
}

このメソッドの 2 回目の呼び出しで、次の 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'

行を参照するもの$statement -> execute();

このエラーを修正するにはどうすればよいですか? ありがとうございました!

更新 (ソリューション) :

args の出力をより詳しく確認する必要があり、エラーが表示されます。echo $args;

ある例では、" AND C.id=123 AND AND AND C.id=456 and C.id="111" AND C.id=789.

私は、別のスクリプトにある、注意したことのない 1 つのケースを変更しました。これで問題が修正されました。

4

1 に答える 1