• ベストアンサー

WHERE id = ? について

SELECT name FROM category WHERE id = ? の=?てどんな意味があるのでしょうか。

質問者が選んだベストアンサー

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.2

 「?」付きのSQLは、prepareしてからexecuteする文に対して使用する構文です。?の部分は、パラメータです。つまり、prepareした後で、パラメータに必要な値をセットしてからexecuteを発行します。  効率に関しては、先の方の回答の通りです。  プログラムにSQL文が埋め込んであるのですから、多分、何度も何度も同じSQLを発行するのでしょう。RDBMSは、このSQL文を受け取るたびに、SQLをコンパイルして、アクセス計画を生成してという作業をするので、コンパイル済み・アクセス計画生成済みというSQL文が使えるメリットは大きいです。  もう一つ、大きなメリットがあります。  それは、エラーチェックというか、パラメータチェックに関する部分です。  SQLインジェクションという技術というか、ハッキング手法があります。これは、例えば、ホームページでフォームに入力された文字列をSQLに渡して検索などに使用する際に発生します。  "SELECT name FROM category WHERE id=" + id_field なんて形でSQL文を作る時は、id_fieldに何が入っているかを必ず事前にチェックしなければなりません。例えば、id_fieldに、「50;DELETE FROM category」なんて値が入っていたら、どうなると思いますか?サーバーは、二つの文章が同時にexecuteされたものと解釈し、素直にカテゴリーテーブルの全データを抹消します。  これは、ごく単純なパターンです。でも、威力は絶大です。  このため、人の入力が関わる総てのパラメータは完全にチェックする必要があります。  ところで、このようなハッキングに使われる総てのパターンをすらすらと言えますか?どれだけの文字をエスケープすればよいか、ちゃんと漏れなくリストアップできますか?  まぁ、これが完全に出来る人は、そうそういません。  パラメータを使用したSQLの場合、パラメータに値を代入し使用する際にRDBMS側でこのようなパターンのチェックをちゃんとやって、必要なエスケープ処理を自前でやってくれます。(MySQLの場合、バージョンによっては、この為に設定が必要なようです。調べておいてください。確か、この機能がデフォルトではoffになっているバージョンが存在したと思います。)  これにより、セキュリティーの面からも安心して利用できるようになります。(少なくとも、自分で作ったチェックルーチンより信用できるでしょう。)  まぁ、こんな利点もありますと言うことで。  一部を変数を用いて変化させる必要があるSQL文は、基本的には、preparを使用し、変数部分は?でパラメータを使用するのが基本的には良いと言うことです。

その他の回答 (1)

回答No.1

SQLを文字列を組み立てて、prepare + executeする場合を考えましょう。 表名や列名、条件式の演算子などを変えた場合は、そのたびにオプティマイザによるアクセス計画の作成が行われます。 一方、SQLの中で、条件式の値部分、挿入値や更新値だけが変わるものを複数回実行したい場合は、? を使うことで、最初の一回だけアクセス計画を作成し、それ以降は既に作成済のアクセス計画を使えることで、オーバーヘッドを抑止できるようになります。 これは、条件式の値を変えながら複数のSELECT文を実行したり、値を変えながら複数回のUPDATE、DELETE、INSERTする場合に有用です。 また、いつくかのRDBMSでは、異なるセッション間でもアクセス計画の再利用ができる機能を提供しているものもあり、これらは各RDBMSにより、クエリキャッシュ、SQLプールなど、いろいろな名前が付いています。 なお、再利用するためには、「キーワード間の空白の個数も同じでなければならない」など、制限がある場合が多いです。 再利用不可の例 "select * from " + 表1 + " where 列1=値" "select * from 表1 where " + "列 between a and b" 再利用可能な例 "select * from 表1 where 列1=?" "select * from 表1 where 列1 in(?,?,?)" "update 表1 set 列2=? where 列1=?"

basi999
質問者

お礼

ありがとうございました

関連するQ&A