QA@IT

検索結果ページで、nullの場合全件数の表示について

9044 PV

勤務地等何かを選択すると、
検索結果が表示されるのですが、
全件表示がうまくいきません。

◆問題:何も選択せずに検索ボタンを押すと、
0件と表示される。
何かを選択すると検索結果が表示される

サンプルデータ:
https://test170701-mh0926.c9users.io/jobsearch/

◆使用言語、
php,sqlite3

◆下記にis not null 等の条件を追加するのかと思うのですが、
上手くいきません。
' where kyujin.area = ? AND ( kyujin.job_type=? OR jikyu>=? OR work_type=? OR gyoukai=?)';

問題が発生しているソース:

<html lang="ja">
<head>
<meta charset="utf-8">
<title>DB連携</title>

</head>
<body>
<?php
require_once "../common_function.php";
// pdoはDBとPHPの間を取り持つオブジェクト

try{
    //var_dump($_POST);
    // POSTしたデータは$_POSTに入っている
    // $_POSTは、連想配列キーが文字列

  // 失敗しそうなコードを書く
   $pdo = new PDO('sqlite:../haken.db'); 

   //$sql = 'select * from kyujin';
//   $sql = 'insert into kyujin (job_type,gyoukai,jikyu) values (?,?,?)';
    // ? はカラムのデータの数だけ必要 ?にしないといけない バインドという
//  $sql= 'select * from kyujin where area = ? OR job_type=? OR jikyu>=? OR work_type=? OR gyoukai=?';

  $sql = 'SELECT '.
' kyujin.id,   jikyu, work_type, gyoukai, keisai_start, keisai_end,  job_type.job_type, area.area'.
' FROM kyujin LEFT JOIN job_type '.
' ON kyujin.job_type=job_type.id '.
' LEFT JOIN area  '.
' ON  kyujin.area = area.id '.
' where kyujin.area = ? AND ( kyujin.job_type=? OR jikyu>=? OR work_type=? OR gyoukai=?)';


  //  $sql= 'select * from kyujin where jikyu=?';
       // sqlの準備 
  $stmt = $pdo -> prepare($sql);

    // $_POSTから値を取得
  //6個を入れる変数を用意
  //勤務地
$todofuken = $_POST["todofuken1"];

  //職種
$syokushu = $_POST["SHOKUSHU_CD"];

  //時給
$jikyu = $_POST["PAY_START"];

  //フリーキーワード
$keyword = $_POST["FREE_KEYWORD"];

  //働き方
$tokucyo = $_POST["TOKUCYO"];

  //業界
$gyoukai = $_POST["GYOUKAI"];

  //データを?に入れることをbindという bindは危険なコードを無害化する
  $stmt->bindParam(1, $todofuken , PDO::PARAM_INT);
  $stmt->bindParam(2, $syokushu[0] , PDO::PARAM_INT);
  $stmt->bindParam(3, $jikyu , PDO::PARAM_INT);
  $stmt->bindParam(4, $tokucyo , PDO::PARAM_STR);
  $stmt->bindParam(5, $gyoukai , PDO::PARAM_STR);
  $stmt->execute();
  $result = $stmt->fetchAll();


  // $resultは配列の配列
  // fetchallは


 echo '<html lang="ja">';
 echo '<head><meta charset="utf-8"></head>';    
 echo '<body><div class="kensaku table_block">';
 echo '<h2 class="center">検索結果は'.count($result).'件です。</h2>';
    // $valueは配列
  // $keyと$valueは空のものを使用する
    foreach ($result as $key => $value ) {
echo '<table>'; 
echo '<tr><th>職種</th><td>'; 
        hyouji( $value['job_type']);
echo '</td></tr>';
echo '<tr><th>時給</th><td>'; 
        hyouji($value['jikyu']);
 echo '</td></tr>';
    echo '<tr><th>業界</th><td>'; 
        hyouji( $value['gyoukai']);
echo '</td></tr>';
echo '<tr><th>勤務地</th><td>'; 
        hyouji( $value['area']);
echo '</td></tr>'; 
echo '</table>';
    }

echo '</div>';  
 echo '</body>';
 echo '</html>';
//     // 実際に入れたいデータを配列に格納する 
//   $bind = array('オフィスワーク','アパレル',1100);

//   $bind[1]; ➡アパレル

/*    $bind = array();
    $bind[0] = 'オフィスワーク';
    $bind[1] = 'アパレル';
    $bind[2] = '1200';*/

    // pdoのprepareメソッドに引数としてsqlを渡す
   /* $stmt = $pdo->prepare($sql);*/

    // $job_type = '電気';
    // $gyoukai = 'メーカー';
    // $jikyu = 2600;

    //   $jikyu = 1300;
    //   $id = 4;

   /* $stmt->bindParam(1, $jikyu, PDO::PARAM_INT); //文字列型PDO::PARAM_STR
    $stmt->bindParam(2, $id, PDO::PARAM_INT);*/
    // $stmt->bindParam(3, $jikyu, PDO::PARAM_INT);

    // stmtオブジェクトにデータを渡す execueは実行という意味
/*    $stmt->execute();
    $result = $stmt->fetchAll();

    // 
    foreach ($result as $key => $value ) {
        hyouji( $value['id'] . "職種:". $value['job_type']  . "時給:". $value['jikyu']
          . "業界:". $value['gyouka']);
    }


   hyouji('データを表示する');*/

} catch(Exception $e){
    // エラーが発生したら即座にこのブロックに移る
    echo $e->getMessage() . "<br>\n";
    // 'ただの文字列' "改行とか/n 変数とか解釈される"
}



?>

</body>
</html>

回答

詳細条件が分かりませんので、条件の一部 where kyujin.area = ? だけ例にとって書きます。

「何かを選択する」とパラメータ ? に「選択」した kyujin.area の値が代入され、その条件で SELECT されるということですよね。

で、「何も選択せず」の場合はパラメータ ? には何が代入されるのでしょうか。何にせよ、SELECT の結果が 0 件ということですと、kyujin.area =「代入した値」が true になるレコードがないということのはずです。

「何も選択せず」の場合は、kyujin.area の値にかかわらず全レコードを抽出したいということだと理解していますが、であれば、

(1) 「何も選択せず」の場合は SELECT クエリの WHERE 句を書き換えて kyujin.area = ? を削除する、または、

(2) WHERE 句の条件を、例えば、WHERE ('ALL' = ?) OR (kyujin.area = ?) のように書き換えて、「何も選択せず」の場合はパラメータ ? に ALL を代入する。

・・・というようにしてはいかがでしょう?

編集 履歴 (0)
  • なるほど。ありがとうございます。
    (2) を使用させて頂き、下記を変更いたしましたが、
    bindParam箇所に下記のエラーが表示されてしまいます。
    「 Call to a member function execute() on a non-object」
    ?が増えたので変数を用意してbindParamを追加しないといけませんよね。
    -
  • 名前によるバインドが使えるんじゃないの? -
  • ? と言うような位置パラメータマーカーの場合は、使われている数だけ、使われている順序で追加する必要があります。 -
ウォッチ

この質問への回答やコメントをメールでお知らせします。