我正在尝试学习编写查询的最佳方法。我也理解保持一致的重要性。到现在为止,我已经随机使用单引号,双引号和反引号而没有任何实际想法。
例:
$query = 'INSERT INTO table (id, col1, col2) VALUES (NULL, val1, val2)';
此外,在上面的例子中,考虑table
,col1
,val1
等可能是变量。
这是什么标准?你是做什么?
我一直在这里阅读类似问题的答案大约20分钟,但看起来这个问题没有明确的答案。
反引号用于表和列标识符,但仅在标识符为MySQL reserved keyword时,或者当标识符包含空格字符或超出有限集的字符时才需要(见下文)。通常建议避免使用保留关键字作为列或尽可能使用表格标识符,避免引用问题。
单引号应该用于VALUES()
列表中的字符串值。 MySQL也支持双引号用于字符串值,但单引号被其他RDBMS更广泛地接受,因此使用单引号而不是双引号是一个好习惯。
MySQL还期望DATE
和DATETIME
文字值单引号为'2001-01-01 00:00:00'
之类的字符串。有关更多详细信息,请参阅the Date and Time Literals文档,特别是使用连字符-
作为日期字符串中的段分隔符的替代方法。
因此,使用您的示例,我会双引号PHP字符串并在值'val1', 'val2'
上使用单引号。 NULL
是一个MySQL关键字,是一个特殊的(非)值,因此没有引用。
这些表或列标识符都不是保留字或使用需要引用的字符,但我还是用反引号引用它们(稍后会详细介绍......)。
不应引用RDBMS原生函数(例如,MySQL中的NOW()
),尽管它们的参数受到已经提到的相同字符串或标识符引用规则的约束。
Backtick (`) table & column ───────┬─────┬──┬──┬──┬────┬──┬────┬──┬────┬──┬───────┐ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ $query = "INSERT INTO `table` (`id`, `col1`, `col2`, `date`, `updated`) VALUES (NULL, 'val1', 'val2', '2001-01-01', NOW())"; ↑↑↑↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑↑↑↑↑ Unquoted keyword ─────┴┴┴┘ │ │ │ │ │ │ │││││ Single-quoted (') strings ───────────┴────┴──┴────┘ │ │ │││││ Single-quoted (') DATE ───────────────────────────┴──────────┘ │││││ Unquoted function ─────────────────────────────────────────┴┴┴┴┘
变量的引用模式不会改变,但如果您打算直接在字符串中插入变量,则必须在PHP中使用双引号。只需确保已正确转义变量以便在SQL中使用。 (It is recommended to use an API supporting prepared statements instead, as protection against SQL injection)。
// Same thing with some variable replacements // Here, a variable table name $table is backtick-quoted, and variables // in the VALUES list are single-quoted $query = "INSERT INTO `$table` (`id`, `col1`, `col2`, `date`) VALUES (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 (?, ?, ?, ?)";
According to MySQL documentation,您不需要使用以下字符集引用(反引号)标识符:
ASCII:
[0-9,a-z,A-Z$_]
(基本拉丁字母,数字0-9,美元,下划线)
您可以使用超出该组的字符作为表或列标识符,例如包括空格,但是您必须引用(反引号)它们。
单引号应该用于字符串值,如VALUES()列表中所示。
反引号通常用于表示标识符,并且不会意外地使用保留关键字。
结合PHP和MySQL,双引号和单引号使您的查询编写时间变得更加容易。
除了所有(解释清楚的)答案之外,还没有提到以下内容,我经常访问此问答。
简而言之; MySQL认为你想在自己的表/列上进行数学运算,并将诸如“电子邮件”之类的连字符解释为`table_name`
减去`column_name`
。
免责声明:所以我认为我会将此作为“FYI”类型的答案添加到那些完全不熟悉数据库并且可能不理解已经描述的技术术语的人那里。
SQL服务器和MySQL,PostgreSQL,Oracle不理解双引号(“)。因此,您的查询应该没有双引号(”),并且应该只使用单引号(')。
回溯(`)是在SQL中使用的可选项,用于表名,数据库名和列名。
如果您尝试在后端编写查询来调用MySQL,那么您可以使用双引号(“)或单引号(')将查询分配给变量,如:
.
如果你的查询中有一个e
语句和/或尝试mail
值为值和/或let query = "select id, name from accounts";
//Or
let query = 'select id, name from accounts';
值为字符串,请使用单引号(')表示这些值:
where
如果你想在使用双引号(“)和单引号(')时避免这种混淆,建议坚持使用单引号(')这将包括反斜杠(),如:
insert
当我们必须为动态分配一些值并执行一些字符串连接时,会出现double(“)或single(')引号的问题:
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.
MySQL中有两种类型的引号:
'
用于封闭字符串文字`
用于包含表和列名称等标识符然后有"
这是一个特例。根据MySQL服务器的sql_mode
,它可以一次用于上述目的之一:
"
字符可用于封装字符串文字,就像'
一样ANSI_QUOTES
模式中,"
字符可用于包围标识符,就像`
一样SELECT "column" FROM table WHERE foo = "bar"
查询将选择字符串文字"column"
,其中列foo
等于字符串"bar"
查询将选择列column
,其中列foo
等于列bar
"
,以便您的代码独立于SQL模式(关于你的问题的SQL性质,上面有很好的答案,但如果你是PHP的新手,这也可能是相关的。)
也许重要的是要提到PHP处理单引号和双引号字符串不同...
单引号字符串是'文字',几乎是WYSIWYG字符串。 PHP解释双引号字符串可能的变量替换(PHP中的反引号不完全是字符串;它们在shell中执行命令并返回结果)。
例子:
$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
反引号通常用于表示identifier
,并且不会意外地使用Reserved Keywords。
例如:
Use `database`;
这里的反引号将帮助服务器理解database
实际上是数据库的名称,而不是数据库标识符。
可以对表名和字段名执行相同的操作。如果用反引号包装数据库标识符,这是一个非常好的习惯。
检查this答案以了解有关反引号的更多信息。
现在关于双引号和单引号(迈克尔已经提到过)。
但是,要定义一个值,您必须使用单引号或双引号。让我们看另一个例子。
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')
在MySQL中,这些符号用于分隔查询`
,"
,'
和()
。
"
或'
用于包含类似字符串的值"26-01-2014 00:00:00"
或'26-01-2014 00:00:00'
。这些符号仅用于字符串,而不是像now
,sum
或max
这样的聚合函数。`
用于封闭表或列名称,例如select `column_name` from `table_name` where id='2'
(
和)
只是包含查询的一部分,例如select `column_name` from `table_name` where (id='2' and gender='male') or name='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
的用途。 (虽然准备好的陈述更好。)
结合PHP和MySQL,双引号和单引号使您的查询编写时间变得更加容易。
$query = "INSERT INTO `table` (`id`, `col1`, `col2`) VALUES (NULL, '$val1', '$val2')";
现在,假设您正在使用直接post变量进入MySQL查询,那么使用它:
$query = "INSERT INTO `table` (`id`, `name`, `email`) VALUES (' ".$_POST['id']." ', ' ".$_POST['name']." ', ' ".$_POST['email']." ')";
这是将PHP变量用于MySQL的最佳实践。
这里有很多有用的答案,通常最终分为两点。
和@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
也是一个指数。
如果表cols和values是变量,那么有两种方法:
用双引号""
完整查询:
$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保留关键字时,请使用返回标记``
。
注意:如果您使用表名表示列名,那么请使用这样的返回标记:
qazxsw poi。来自反叛的qazxsw poi qazxsw poi。