首页 文章

何时在MySQL中使用单引号,双引号和后退标记

提问于
浏览
531

我正在尝试学习编写查询的最佳方法 . 我也理解保持一致的重要性 . 到现在为止,我已经随机使用了单引号,双引号和后退,没有任何实际想法 .

例:

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

此外,在上面的示例中,请考虑 "table," "col[n]," and "val[n]" 可能是变量 .

这是什么标准?你是做什么?

我一直在这里阅读类似问题的答案大约20分钟,但看起来这个问题没有明确的答案 .

12 回答

  • 12

    反引号用于表和列标识符,但仅在标识符为MySQL reserved keyword时,或者当标识符包含空格字符或超出限制集的字符时才需要(见下文) . 通常建议避免使用保留关键字作为列或尽可能使用表格标识符,避免引用问题 .

    单引号应该用于 VALUES() 列表中的字符串值 . MySQL也支持双引号用于字符串值,但是单引号被其他RDBMS更广泛地接受,因此使用单引号而不是双引号是一个好习惯 .

    MySQL还希望 DATEDATETIME 文字值作为字符串单引,如 '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,美元,下划线)

    您可以使用超出该组的字符作为表或列标识符,例如包括空格,但是您必须引用(反引号)它们 .

  • 2

    MySQL中有两种类型的引号:

    • ' 用于包含字符串文字

    • 
      

    然后有 " 这是一个特例 . 它可以一次用于上述目的之一,具体取决于MySQL服务器的sql_mode

    • 默认情况下, " 字符可用于包含字符串文字,就像 ' 一样

    • ANSI_QUOTES模式中, " 字符可用于包围标识符,就像 ```

    以下查询将根据SQL模式生成不同的结果(或错误):

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

    ANSI_QUOTES已禁用

    查询将选择字符串文字 "column" ,其中列 foo 等于字符串 "bar"

    ANSI_QUOTES已启用

    该查询将选择列 column ,其中 foo 列等于 bar

    何时使用什么

    • 我建议您避免使用 " ,以便您的代码独立于SQL模式

    • 始终引用标识符,因为这是一个很好的做法(关于SO的很多问题讨论这个)

  • 10

    (关于你的问题的SQL性质,上面有很好的答案,但如果你是PHP的新手,这也可能是相关的 . )

    也许重要的是要提到PHP处理单引号和双引号字符串不同...

    单引号字符串是'文字',几乎是所见即所得字符串 . 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
    
  • 520

    反引号通常用于指示 identifier 以及 safe 意外使用Reserved Keywords .

    例如:

    Use `database`;
    

    这里的反引号将帮助服务器理解 database 实际上是数据库的名称,而不是数据库标识符 .

    可以对表名和字段名执行相同的操作 . 如果用反引号包装数据库标识符,这是一个非常好的习惯 .

    查看此答案以了解有关反引号的更多信息 .


    现在关于双引号和单引号(迈克尔已经提到过) .

    但是,要定义一个值,您必须使用单引号或双引号 . 让我们看另一个例子 .

    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

    基本上在Mysql中,有查询 ``` , "'() 这些标识符 .

    • "' 用于封闭字符串,如值 "26-01-2014 00:00:00"'26-01-2014 00:00:00' . 这些标识符仅用于字符串而非聚合函数,如 now() or sum ,max 等 .

    • ``` 用于封闭表格或表格列,例如从 table_name 中选择 column_name ,其中id = '2'

    • () 仅用于封闭查询部分,例如从 table_name 中选择 column_name ,其中(id = '2'和gender = 'male')或name = 'rakesh' .

  • 9

    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 的用途 . (虽然准备好的陈述更好 . )

  • 29

    结合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的最佳实践 .

  • 11

    如果表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保留关键字时,请使用返回标记 ```` .

    Note: 如果您使用表名表示列名,请使用如下的返回标记:

    table_name . column_name < - 注意:从后面的刻度中排除 . .

  • 7

    这里有很多有用的答案,通常最终分为两点 .

    • BACKTICKS(`)用于标识符名称 .

    • SINGLE QUOTES(')用于值 .

    和@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 也是一个指数 .

  • 0

    单引号应该用于字符串值,如VALUES()列表中所示 .

    反引号通常用于表示标识符,并且不会意外地使用保留关键字 .

    结合PHP和MySQL,双引号和单引号使您的查询编写时间变得更加容易 .

  • 101

    除了所有(解释清楚的)答案之外,还没有提到以下内容,我经常访问此问答 .

    简而言之; MySQL thinks you want to do math 在其自己的表/列上,并将"e-mail"等连字符解释为 e minus mail .


    Disclaimer: 所以我认为我会将此作为一种"FYI"类型的答案添加到那些对数据库工作完全陌生并且可能不理解已经描述的技术术语的人 .

  • 8

    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\'';
    

    当我们必须为动态分配一些值并执行一些字符串连接时,会出现double(“)或single(')引号的问题:

    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 + '\'';
    

    如果需要进一步清关请遵循quotes in JavaScript

相关问题