
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を使用し、変数部分は?でパラメータを使用するのが基本的には良いと言うことです。
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=?"
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
- MySQL 書籍の内容はまともでしょうか? 1 2023/01/22 03:07
- MySQL 共通点はあります。何が違うのでしょうか? 1 2023/01/27 05:22
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- Access(アクセス) 実行時エラー3131 FROM 句の構文エラーです について 7 2022/06/13 15:45
- PHP php my adminより取り出したデータ表示 2 2022/06/15 11:56
- MySQL 下記の問合せを行うクエリを、PhpMyAdminで作成して実行せよ。 「名前(first name) 1 2023/06/24 13:03
- Oracle SQL update方法 2 2022/06/22 14:07
- PHP 重複を防ぐ記述について教えて下さい。 3 2023/04/03 14:35
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・【お題】甲子園での思い出の残し方
- ・【お題】動物のキャッチフレーズ
- ・人生で一番思い出に残ってる靴
- ・これ何て呼びますか Part2
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・あなたが好きな本屋さんを教えてください
- ・かっこよく答えてください!!
- ・一回も披露したことのない豆知識
- ・ショボ短歌会
- ・いちばん失敗した人決定戦
- ・性格悪い人が優勝
- ・最速怪談選手権
- ・限定しりとり
- ・性格いい人が優勝
- ・これ何て呼びますか
- ・チョコミントアイス
- ・単二電池
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・泣きながら食べたご飯の思い出
- ・一番好きなみそ汁の具材は?
- ・人生で一番お金がなかったとき
- ・カラオケの鉄板ソング
- ・自分用のお土産
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルの関数について教えて...
-
エクセルで最後の文字だけ置き...
-
sqlで、600行あるテーブルを100...
-
select文のwhere句に配列を入れ...
-
Updateの複数テーブル条件時のL...
-
重複しない乱数生成のVBAマクロ...
-
auto_incrementを任意の数字か...
-
データベース mysql
-
マイクラPC版のコマンドで効率...
-
1テーブル&複数レコードの更新...
-
INで抽出した順番に並び替え(S...
-
MySQLで結果変数が取得できません
-
order byですが、数値で指定す...
-
DB設計について
-
副問合せの書き方について
-
UPDATE文とWHERE句
-
ストアドのエラーについて
-
【SQLクエリ】日替わりで表示さ...
-
【MySQL】auto_incrementの値を...
-
カラム名でseqとidではどちらが...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
select文のwhere句に配列を入れ...
-
VIEWの元のテーブルのindexって...
-
SQLにて特定の文字を除いた検索...
-
sqlで、600行あるテーブルを100...
-
SQLサーバから、項目の属性(型...
-
selectした大量データをinsert...
-
Access パラメータクエリをcsv...
-
画像とカテゴリーを出力したい...
-
WordpressのContact form 7でzi...
-
【Transact-sql】 execの結果を...
-
SQL Left Join で重複を排除す...
-
エラー 1068 (42000): 複数の主...
-
ある条件の最大値+1を初番する...
-
マイクラPC版のコマンドで効率...
-
クエリ表示と、ADOで抽出したレ...
-
Unionした最後にGROUP BYを追加...
-
PL/SQLの変数について
-
全角文字を含む行を検索
おすすめ情報