web-dev-qa-db-ja.com

MySQLで一重引用符、二重引用符、およびバッククォートを使用する場合

私はクエリを書くための最良の方法を学ぼうとしています。私はまた、一貫していることの重要性を理解しています。今まで、私は何も考えずにランダムに一重引用符、二重引用符、およびバッククォートを使用してきました。

例:

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

また、上記の例では、tablecol1val1などが変数になることがあります。

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

私はここで約20分間、同様の質問に対する答えを読んでいますが、この質問に対する明確な答えはないようです。

572
Nate

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

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

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

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

これらのテーブルや列の識別子は予約語でも引用符を必要とする文字を利用するものでもありませんが、私はとにかくそれらをバッククォートで引用しました(詳細は後述)。

RDBMSに固有の関数(たとえば、MySQLのNOW())は引用符で囲まないでください。ただし、それらの引数は、すでに述べたものと同じ文字列または識別子の引用規則に従います。

バッククォート( `)
表と列───────┬────────────────────────────── ┬────┬──────────0057 
↓↓↓↓↓↓↓↓↓↓↓↓
 $ query = "INSERT INTO table( `id`、` col1`、 `col2`、` date`、 `updated`)
値(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') "; 

準備済みステートメント

準備文で作業するときは、文を参照して、文のプレースホルダを引用符で囲む必要があるかどうかを判断してください。他の言語のほとんどのプリペアドステートメントAPIと同様に、PHP、PDO、およびMySQLiで利用可能な最も普及している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、ドル、アンダースコア)

あなたは、例えば空白を含む、テーブルやカラムの識別子として、そのセットを超えた文字を使うことができますが、その場合は must quote(バックティック)にしてください。

554

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

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

そして、特別な場合である"があります。 MySQLサーバの sql_mode に応じて、上記の目的の one に同時に使用できます。

  1. デフォルトで "文字は、'と同じように文字列リテラルを囲むために使用できます。
  2. ANSI_QUOTES モードでは、"文字は`と同じように識別子を囲むために使用できます。

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

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

ANSI_QUOTESが無効

クエリは文字列リテラル"column"を選択します。ここで、列fooは文字列"bar"と同じです。

ANSI_QUOTESが有効

照会は列columnを選択します。ここで、列fooは列barと同じです。

何を使うか

  • コードがSQLモードから独立するように、"を使用しないことをお勧めします。
  • それは良い習慣なので常に識別子を引用してください(これについてはSOに関するかなりの数の質問)
108
Salman A

(あなたの質問の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
29
Chris Trahey

バックティックは一般にidentifierを示すために使用され、また誤って Reserved Keywords )を使用しないようにsafeに​​するために使用されます。

例えば:

Use `database`;

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

テーブル名とフィールド名についても同様です。データベース識別子をバッククォートで囲むと、これは非常に良い習慣です。

バッククォートについてもっと理解するために this answerをチェックしてください。


今二重引用符と一重引用符について(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')
19
Starx

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

  1. "または'は、文字列のような値"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'

12
Kumar Rakesh

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の目的です。 (準備されたステートメントが優れていますが)

11
xdazz

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

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

それでは、MySQLクエリに直接post変数を使用しているとしましょう。それを次のように使用します。

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

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

10
vipul sorathiya

テーブルの列と値が変数の場合、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` < - 注:バックティックから.を除外してください。

9
diEcho

ここには多くの有益な答えがありました、一般的に2つのポイントに最高に達します。

  1. BACKTICKS( `)は識別子名の周りに使われます。
  2. 単一引用符( ')は値の周りに使用されます。

と@MichaelBerkowskiが言ったように

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

ただし、識別子が予約済みキーワードになることも、空白または制限されたセットを超える文字数を含むこともできない場合もありますが、必ずそれらを囲む必要はありません。

123E10は有効な識別子名ですが、有効なINTEGERリテラルでもあります。

[どのようにしてそのような識別子名を取得するかについて詳しく説明することなく]、123456e6という名前の一時テーブルを作成したいとします。

バッククォートにエラーはありません。

DB [XXX]> create temporary table `123456e6` (`id` char (8));
Query OK, 0 rows affected (0.03 sec)

バッククォートを使用していない場合はエラー。

DB [XXX]> create temporary table 123451e6 (`id` char (8));
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '123451e6 (`id` char (8))' at line 1

ただし、123451a6は完全に優れた識別子名です(バックティックはありません)。

DB [XXX]> create temporary table 123451a6 (`id` char (8));
Query OK, 0 rows affected (0.03 sec)

これは完全に1234156e6も指数関数的な数だからです。

9
user5574289

VALUES()リストのように、文字列値には一重引用符を使用する必要があります。

バックティックは通常、識別子を示すために使用され、また予約キーワードを誤って使用しないようにしてください。

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

7
john igneel

(よく説明された)すべての答えのほかに、次のようなことは述べられていません。私はこの質疑応答を頻繁に訪れます。

手短に; MySQLは、あなたが自分自身のテーブル/カラムに対して数学 を実行したいと考えており、 "E-mail"のようなハイフンをe - mailとして解釈します。


免責事項: それで私はこれを「FYI」タイプの答えとしてデータベースを扱うことに全く慣れていないそして既に述べられた技術用語を理解していないかもしれない人々のために追加すると思いました。

2

SQLサーバーとMySQL、PostgreySQL、Oracleは二重引用符( ")を理解していません。したがって、クエリは二重引用符(")から解放され、一重引用符( ')のみを使用する必要があります。

バックトリップ( `)は、SQLでの使用はオプションであり、テーブル名、データベース名、および列名に使用されます。

MySQLを呼び出すためにバックエンドにクエリを書き込もうとしている場合は、次のようにクエリに変数を割り当てるために二重引用符( ")または一重引用符( ')を使用できます。

let query = "select id, name from accounts";
//Or
let query = 'select id, name from accounts';

クエリにwhereステートメントがある場合、および/または文字列であるinsertの値および/または値のupdateを使用する場合は、次のように単一引用符( ')を使用します。

let querySelect = "select id, name from accounts where name = 'John'";
let queryUpdate = "update accounts set name = 'John' where id = 8";
let queryInsert = "insert into accounts(name) values('John')";

//Please not that double quotes are only to be used in assigning string to our variable not in the query
//All these below will generate error

let querySelect = 'select id, name from accounts where name = "John"';
let queryUpdate = 'update accounts set name = "John" where id = 8';
let queryInsert = 'insert into accounts(name) values("John")';

//As MySQL or any SQL doesn't understand double quotes("), these all will generate error.

二重引用符( ")と一重引用符( ')を使用するときにこの混乱を避けたい場合は、次のようにバックスラッシュ()を含めることをお勧めします。

let query = 'select is, name from accounts where name = \'John\'';

二重( ")または一重( ')引用符の問題は、動的に値を割り当て、文字列連結を次のように実行しなければならない場合に発生します。

let query = "select id, name from accounts where name = " + fName + " " + lName;
//This will generate error as it must be like name = 'John Smith' for SQL
//However our statement made it like name = John Smith

//In order to resolve such errors use
let query = "select id, name from accounts where name = '" + fName + " " + lName + "'";

//Or using backslash(\)
let query = 'select id, name from accounts where name = \'' + fName + ' ' + lName + '\'';

さらにクリアランスが必要な場合は JavaScriptの引用符に従ってください

0
NAVIN