2012-03-02 13 views
2

ブール値(別名tinyint、1または0)を含むMySQLの列「public」があります。クエリを行うときは、一般的にパブリックカラムの値は気にしないので、デフォルトではアンダースコア(MySQLワイルドカード)を渡します。場合によっては、「public = 0」または「public = 1」と一致する行のみが必要になるので、下線を0または1で上書きします。これは私が今までに与えた最も明白な説明ではありません:PDOパラメータとして「真または偽」をバインドする

public function get_hunts($public = '_') { 
    $sth = $this->_db->prepare("SELECT * FROM hunts WHERE(user_id = :user AND public = :public)"); 
    $sth->bindParam(':user', $this->_id); 
    $sth->bindParam(':public', $public); 
    $sth->execute(); 
    $result = $sth->fetchAll(PDO::FETCH_ASSOC); 

    return $result; 
} 

//get any result 
get_results(); 

//get only public results 
get_hunts(1) 

このようにアンダースコア(私も一般的なワイルドカード%を試してみました)をバインドすると、クエリが失敗します。これを達成するより良い方法は何ですか?

答えて

3

任意のワイルドカード文字を使用するには、あなたはクエリビルダあなたが構築アプローチのいくつかの種類を取る必要があるだろう、そうでない場合

AND public LIKE :public 

に等しいのではなく、LIKE比較を使用する必要があるだろうWHEREは、関数の引数に基づく条件です。

public function get_hunts($public = null) { 
    $where = array(
     'user_id = :user' 
    ); 
    $params = array(
     ':user' => $this->_id 
    ); 

    if (null !== $public) { 
     $where[] = 'public = :public'; 
     $params[':public'] = (boolean) $public; 
    } 

    $query = 'SELECT * FROM hunts WHERE ' . implode(' AND ', $where); 
    $sth = $this->_db->prepare($query); 
    $sth->execute($params); // same as binding 

    return $sth->fetchAll(PDO::FETCH_ASSOC); 
} 
3

バインドパラメータはシンプルなリテラルのためだけなので、あなたは、テーブル名とカラム名(識別子)またはIN句(リテラルのリスト)のようなものをバインドすることはできません。

だから、あなたが望むものは簡単にはできません。

function get_hunts($public=null) { 
    // assuming hunts.public is defined as NOT NULL 
    $sql = "SELECT * FROM hunts WHERE user_id=:user"; 
    if ($public!==null) { 
     $sql .= ' AND public=:public'; 
    } 
    $sth = $this->_db->prepare($sql); 
    $sth->bindParam(':user', $this->_id); 
    if ($public!==null) { 
     $sth->bindParam(':public', $public, PDO::PARAM_INT); 
    } 
    $sth->execute(); 
    return $sth->fetchAll(PDO::FETCH_ASSOC); 
} 

あなたが本当に別のクエリを使用しない場合、あなたはCASE式でハックソリューションを使用することができます:あなたが本当に何をすべき

は、別のクエリを使用しています。

SELECT * FROM hunts WHERE user_id=:user 
    AND public= 
    CASE :public WHEN 0 THEN 0 WHEN 1 THEN 1 ELSE public END 

あなたはバインド値が0または1でない場合は、WHERE条件は、それ自体に等しいので、常に真であるとpublicが必要になります。それ以外の場合は、:publicの値が使用されます。

+0

よく考えられた答えをありがとう。今のところ、私は、 "public =:public"を "public LIKE:public"と交換しました。フィルは示唆したとおり、ワイルドカードを使用できます。純粋に迅速かつ簡単な修正だったからです。あなたの答えとPhilの長い方の選択肢はおそらくもっと良い解決策かもしれないので、私は何かを学びました。 – MartinAnsty

+0

+1「CASE」の使い方がいいです。参考までに、2番目の ':user'バインディングは':public'でなければなりません – Phil

+0

@MartinAnsty提案されていません。あなたは怠惰と無知から間違った解決策を選択します –

関連する問題