1

データベースにテキスト (Products CodeおよびProducts Variant) を保持する 2 つの列があります。

たとえば
Products Code、次のテキストを保持します: C050101、C070104
および
Products Variant次のテキストを保持します: RED、NULL

すべての行を選択したいWHERE Code = Products Code AND Variant = Products Variant
上記の例に基づいて、2行を取得する必要があります。
最初の行、 WHERE Code=C050101 and Variant=RED
2番目の行WHERE Code=C070104 and Variant IS NULL<< IS NULL

私はそれを行う方法がわかりません...
すべての行のみを選択する必要がある場合は、その方法を知っていますWHERE Code = Products Code>>

$arr = array('C050101','C070104');
$inclause = implode(',',array_fill(0,count($arr),'?'));
$stockstmt = $pdo->prepare(sprintf("SELECT `id`, `WebTitle`, `StockCode` FROM `stock` WHERE `StockCode` IN(%s)",$inclause));
$stockstmt->execute($arr);

よろしくお願いします。
ありがとう!

4

1 に答える 1

2

INこれには述語を使用できません。これは、とのIN比較方法のみを知って=おり、NULL を処理するために別の方法で比較する必要があるためです。

MySQL には、 NULL=NULL が true であり、NULL = 'RED' が false であることを認識している、非標準のヌル セーフ等価演算子があります。<=>

MySQL 以外のものを使用する場合、RDBMS はIS [NOT] DISTINCT同様の述語の標準 SQL 構文をサポートしている可能性があります。

私は以下をテストしましたが、動作します:

$arr = array('C050101','RED', 'C070104', NULL);

$sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock`
  WHERE (`StockCode`, `StockVariant`) <=> (?, ?)
     OR (`StockCode`, `StockVariant`) <=> (?, ?)";

$stockstmt = $pdo->prepare($sql);
if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }

$status = $stockstmt->execute($arr);
if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }

述語のリストをどのように作成するかは、あなたに任せます。


あなたのコメントについて:

リテラル文字列 'NULL' を使用して、欠落している値や適用できない値を表すことはお勧めできません。これが、SQL における NULL の目的です。

述語の構築をより動的にする関数が必要な場合は、これを試してください。

function lookformultiplethings(array $arr)
{
  global $pdo;

  $where = array();
  $values = array();
  foreach ((array) $arr as $term) {
    $where[] = '('
        . join(',', array_map(function ($col) {return "`$col`";}, array_keys($term)))
        . ') <=> ('
        . join(',', array_fill(0,count($term),'?'))
        . ')';
    $values = array_merge($values, array_values($term));
  }
  $sql = "SELECT `id`, `WebTitle`, `StockCode` FROM `stock` ";
  if ($where) {
    $sql .= "WHERE " . join(' OR ', $where);
  }

  $stockstmt = $pdo->prepare($sql);
  if ($stockstmt === false) { die(print_r($pdo->errorInfo(), true)); }

  $status = $stockstmt->execute($values);
  if ($status === false) { die(print_r($stockstmt->errorInfo(), true)); }

  print_r($stockstmt->fetchAll());
}

lookformultiplethings(array(
  array('StockCode' => 'C050101', 'StockVariant' => 'RED'),
  array('StockCode' => 'C070104', 'StockVariant' => 'NULL'),
));

渡す配列のキーが正当な列名であることに注意してください。つまり、実際の列のホワイトリストと照らし合わせて検証しない限り、ユーザー入力によって列名が設定されないようにしてください。

于 2012-11-30T21:20:52.873 に答える