727

クエリを作成する最良の方法を学ぼうとしています。一貫性を持つことの重要性も理解しています。これまで、シングル クォーテーション、ダブル クォーテーション、バッククォートを何も考えずにランダムに使用してきました。

例:

$query = 'INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)';

また、上記の例ではtablecol1val1、 などが変数である可能性があると考えてください。

これの基準は何ですか?職業はなんですか?

ここで同様の質問への回答を約 20 分間読んでいますが、この質問に対する決定的な回答はないようです。

4

14 に答える 14

704

バッククォートはテーブルとカラムの識別子に使用されますが、識別子がMySQLの予約済みキーワードである場合、または識別子に空白文字または制限されたセットを超える文字が含まれている場合にのみ必要です(以下を参照) 予約済みキーワードの使用を避けることをお勧めします。可能な場合は列またはテーブルの識別子として、引用の問題を回避します。

リストのような文字列値には、一重引用符を使用する必要がありVALUES()ます。二重引用符は MySQL でも文字列値に対してサポートされていますが、単一引用符は他の RDBMS でより広く受け入れられているため、二重引用符ではなく単一引用符を使用することをお勧めします。

MySQL はまた、リテラル値が のような文字列として単一引用符で囲まれていることを想定DATEDATETIMEています'2001-01-01 00:00:00'詳細については、日付と時刻のリテラルのドキュメントを参照してください。特に-、日付文字列のセグメント区切り文字としてハイフンを使用する代わりの方法については、こちらを参照してください。

あなたの例を使用すると、PHP文字列を二重引用符で囲み、値に一重引用符を使用します'val1', 'val2'NULLは MySQL キーワードであり、特別な (非) 値であるため、引用符で囲まれていません。

これらのテーブルまたは列の識別子はいずれも予約語ではなく、引用符が必要な文字も使用していませんが、とにかくバッククォートで引用しています (これについては後で詳しく説明します...)。

RDBMS 固有の関数 ( NOW()MySQL など) は引用符で囲む必要はありませんが、それらの引数は、前述の同じ文字列または識別子の引用規則に従います。

バッククォート (`)
表と列 ────────┬──────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬ ────────┐
                      ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
$query = " INSERT INTO `table` (`id`, `col1`, `col2`, `date`, `updated`)
                       VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW()) ";
                               ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑
引用されていないキーワード──────┴┴┴┘ │ │ │ │ │││││
単一引用符 (') 文字列 ────────────┴────┴──┴────┘ │ │││││
シングルクォート (') DATE ────────────────────────────┴──────────┘ ││││ │
引用されていない関数 ──────────────────────────────────────────┴┴┴┴┘    

可変補間

変数の引用パターンは変更されませんが、変数を文字列に直接挿入する場合は、PHP で二重引用符で囲む必要があります。SQL で使用する変数を適切にエスケープしたことを確認してください。(代わりに、SQL インジェクションに対する保護として、準備済みステートメントをサポートする API を使用することをお勧めします)。

// いくつかの変数置換で同じこと
// ここで、変数テーブル名 $table はバッククォートで囲まれ、変数
// VALUES リスト内は一重引用符で囲みます
$query = "INSERT INTO `$table` (`id`, `col1`, `col2`, `date`) 値 (NULL, '$val1' , '$val2' , '$date' )";

準備されたステートメント

準備済みステートメントを使用する場合は、ドキュメントを参照して、ステートメントのプレースホルダーを引用する必要があるかどうかを判断してください。PHP、PDO、および MySQLi で利用可能な最も一般的な APIは、他の言語のほとんどの準備済みステートメント API と同様に、引用符で囲まれていないプレースホルダーを想定しています。

// PDO example with named parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (:id, :col1, :col2, :date)";

// MySQLi example with ? parameters, unquoted
$query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`) VALUES (?, ?, ?, ?)";

識別子でバッククォートを必要とする文字:

MySQL のドキュメント によると、次の文字セットを使用して識別子を引用符 (バッククォート) で囲む必要はありません。

ASCII: [0-9,a-z,A-Z$_](基本的なラテン文字、0 ~ 9 の数字、ドル、アンダースコア)

テーブルまたは列の識別子として、空白などのセット以外の文字を使用できますが、それらを引用符 (バッククォート) で囲む必要があります。

また、数字は識別子として有効な文字ですが、数字だけで識別子を構成することはできません。その場合は、バッククォートで囲む必要があります。

于 2012-07-04T01:57:55.800 に答える
145

MySQL には 2 種類の引用符があります。

  1. '文字列リテラルを囲むため
  2. `テーブル名や列名などの識別子を囲むため

そして"、特殊なケースがあります。MySQL サーバーの状況に応じて、上記の目的のいずれかで一度に使用できsql_modeます。

  1. デフォルトでは、"文字を使用して文字列リテラルを囲むことができます'
  2. ANSI_QUOTESモードでは、文字"を使用して識別子を囲むことができます`

次のクエリは、SQL モードに応じて異なる結果 (またはエラー) を生成します。

SELECT "column" FROM table WHERE foo = "bar"

ANSI_QUOTES 無効

クエリは、列が文字"column"fooと等しい文字列リテラルを選択します"bar"

ANSI_QUOTES が有効

クエリは、列columnが列fooと等しい列を選択しますbar

いつ何を使うか

  • "コードが SQL モードに依存しないようにするため、使用を避けることをお勧めします。
  • それは良い習慣であるため、常に識別子を引用してください(SOに関するかなりの数の質問がこれについて議論しています)
于 2013-01-02T14:17:35.703 に答える
35

(質問の SQL の性質に関しては上記の良い回答がありますが、これは PHP を初めて使用する場合にも関連する可能性があります。)

おそらく、PHP は一重引用符と二重引用符の文字列を異なる方法で処理することに言及することが重要です...

単一引用符で囲まれた文字列は「リテラル」であり、ほぼ WYSIWYG 文字列です。二重引用符で囲まれた文字列は、可能な変数置換のために PHP によって解釈されます (PHP のバッククォートは厳密には文字列ではありません。シェルでコマンドを実行し、結果を返します)。

例:

$foo = "bar";
echo 'there is a $foo'; // There is a $foo
echo "there is a $foo"; // There is a bar
echo `ls -l`; // ... a directory list
于 2012-07-04T02:03:01.137 に答える
28

バッククォートは通常、予約済みキーワードを誤って使用しidentifierないようにするために使用されます

例えば:

Use `database`;

databaseここで、バッククォートは、実際にはデータベース識別子ではなく、データベースの名前であることをサーバーが理解するのに役立ちます。

テーブル名とフィールド名についても同じことができます。データベース識別子をバッククォートでラップする場合、これは非常に良い習慣です。

バックティックの詳細については、この回答を確認してください。


次に、二重引用符と単一引用符について (Michael は既に言及しています)。

ただし、値を定義するには、一重引用符または二重引用符を使用する必要があります。別の例を見てみましょう。

INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, title1);

ここでは、意図的に を引用符で囲むのを忘れてtitle1います。これで、サーバーは をtitle1列名 (つまり、識別子) として受け取ります。したがって、それが値であることを示すには、二重引用符または単一引用符を使用する必要があります。

INSERT INTO `tablename` (`id, `title`) VALUES ( NULL, 'title1');

現在、PHP と組み合わせて、二重引用符と単一引用符を使用すると、クエリの作成時間が大幅に短縮されます。質問のクエリの修正版を見てみましょう。

$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

ここで、PHP で二重引用符を使用して変数$val1$val2作成し、それらの値を使用して完全に有効なクエリを作成します。お気に入り

$val1 = "my value 1";
$val2 = "my value 2";
$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

作る予定です

INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, 'my value 1', 'my value 2')
于 2012-07-04T02:00:29.297 に答える
22

MySQL では、これらの記号は、クエリ`、、およびを区切るために使用されます。"'()

  1. "orは、文字列のような値or'を囲むために使用されます。これらの記号は、 、、またはなどの集約関数ではなく、文字列のみを対象としています。"26-01-2014 00:00:00"'26-01-2014 00:00:00'nowsummax

  2. ` テーブル名または列名を囲むために使用されます。select `column_name` from `table_name` where id='2'

  3. (クエリの一部を)囲むだけ select `column_name` from `table_name` where (id='2' and gender='male') or name='rakesh'です。

于 2017-01-03T11:42:10.520 に答える
15

MySQL と PHP の文字列リテラルは同じです。

文字列は、単一引用符 ("'") または二重引用符 (""") 文字で囲まれた一連のバイトまたは文字です。

したがって、文字列に一重引用符が含まれている場合は、二重引用符を使用して文字列を引用できます。また、二重引用符が含まれている場合は、一重引用符を使用して文字列を引用できます。ただし、文字列に一重引用符と二重引用符の両方が含まれている場合は、文字列を引用するために使用されたものをエスケープする必要があります。

ほとんどの場合、SQL 文字列値には一重引用符を使用するため、PHP 文字列には二重引用符を使用する必要があります。

$query = "INSERT INTO table (id, col1, col2) VALUES (NULL, 'val1', 'val2')";

また、PHP の二重引用符で囲まれた文字列で変数を使用できます。

$query = "INSERT INTO table (id, col1, col2) VALUES (NULL, '$val1', '$val2')";

しかし、$val1または$val2一重引用符が含まれていると、SQL が間違ったものになります。そのため、SQL で使用する前にエスケープする必要があります。それがmysql_real_escape_string目的です。(ただし、準備されたステートメントの方が優れています。)

于 2012-07-04T02:16:30.993 に答える
14

PHP と MySQL を組み合わせると、二重引用符と単一引用符を使用して、クエリの作成時間が大幅に短縮されます。

$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";

ここで、MySQL クエリにダイレクト ポスト変数を使用している場合、次のように使用します。

$query = "INSERT INTO `table` (`id`, `name`, `email`) VALUES (' ".$_POST['id']." ', ' ".$_POST['name']." ', ' ".$_POST['email']." ')";

これは、PHP 変数を MySQL で使用するためのベスト プラクティスです。

于 2015-06-16T10:25:05.737 に答える
12

テーブルの列と値が変数の場合、次の 2 つの方法があります。

""完全なクエリを二重引用符で囲みます。

$query = "INSERT INTO $table_name (id, $col1, $col2)
                 VALUES (NULL, '$val1', '$val2')";

または

 $query = "INSERT INTO ".$table_name." (id, ".$col1.", ".$col2.")
               VALUES (NULL, '".$val1."', '".$val2."')";

一重引用符付き'':

$query = 'INSERT INTO '.$table_name.' (id, '.$col1.', '.$col2.')
             VALUES (NULL, '.$val1.', '.$val2.')';

``列/値の名前が MySQL の予約済みキーワードに似ている場合は、バック ティックを使用します。

注:テーブル名で列名を示している場合は、次のようにバック ティックを使用します。

`table_name`. `column_name` <-- 注:. バック ティックから除外します。

于 2012-07-04T02:03:00.667 に答える