【问题标题】:Error in SQL syntax, check for right syntax to use near '0' at line 1SQL 语法错误,请检查在第 1 行的“0”附近使用的正确语法
【发布时间】:2012-07-13 09:38:57
【问题描述】:

我遇到了标题中提到的错误,这是我的PHP文件中的代码,我尝试重新查询,但未能纠正错误,谁能告诉我为什么会出现这种错误,是我形成错误的方式不正确?我看过一些类似的帖子,但我从这些帖子中知道问题应该是我的查询,但我不知道如何更改它。所以我可以请你帮忙告诉我查询的问题在哪里,这绝对可以帮助我弄清楚我的概念。

$query = "SELECT * 
    FROM Tech AS T, Client AS C, Site AS S, Log AS L 
    WHERE T.TechID=L.TechID, C.ClientID=L.ClientID, S.SiteID=L.SiteID";
if($sort=="Tech")
   $query += "ORDER BY T.TechName ASC, L.Time DSC";
else if($sort=="Client")
   $query += "ORDER BY C.ClientName ASC, L.Time DSC";
$result = mysql_query($query) or die('Error! ' . mysql_error());; 
print "Real-Time check in/check out<br>";
print "<table><th><td>Tech</td><td>Client</td><td>Site</td>";
print "<td>Date and Time</td><td>Type</td></th>";
while($row = mysql_fetch_array($result)){
print "<tr><td>".$row['T.TechName']."</td>";
print "<td>".$row['C.ClientName']."</td>";
print "<td>".$row['S.SiteName']."</td>";
print "<td>".$row['L.Time']."</td>";
print "<td>".$row['L.Type']."</td></tr>";
}
print "</table>";

以下是错误信息:

错误!您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在第 1 行的“0”附近使用正确的语法

【问题讨论】:

  • 请注意,or die(mysql_error()) 不应该出现在生产代码中,因为die 会破坏 HTML 输出,并且数据库错误消息不应该像discloses too much information 那样向非管理员用户透露。更好的方法是正确实现错误处理(并使用 PDO 代替已弃用的过时 mysql 扩展)。
  • 你不应该在这里使用连接吗?而且我认为您忘记在“ORDER BY”字符串中添加空格。
  • Implicit joins 不应用于支持explicit joins
  • 请注意,每当您生成 SQL 语句并遇到语法错误时,您应该获取生成的实际语句(并发布它),而不仅仅是生成语句的代码。跨度>
  • SO 使用问答形式,而不是论坛形式。问题不应包含答案,例如更正的代码。把它留给答案。

标签: php mysql


【解决方案1】:

看不到零可能来自哪里..

但是在您将 ORDER BY 附加到查询的行中,您缺少一个空格。

在原始$query 的末尾添加一个空格,或者在$query += 的开头添加一个空格

对于降序,它应该是DESC 而不是DSC

对于 PHP,+= 也应该是 .=

【讨论】:

  • 哦,原来如此,因为我只是按照写C++的方式,所以犯了这种粗心的错误,对不起。
  • 在切换语言时一定要检查(小)差异;)
  • 请问为什么切换到desc后逐句的顺序还是有错误?这是错误消息“错误!您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以在第 3 行的 'T.TechName ASC, L.Time DESC' 附近使用正确的语法”
  • 抱歉,我相信你不能同时使用 ASC 和 DESC。只需在末尾或查询时使用 DESC OR ASC
  • 我认为这样做是可以的,因为当我像上面给出的代码一样更改它时,它现在没有问题(至少它现在可以工作)
【解决方案2】:

AND 而不是逗号,

ORDER之前的空格

.= 而不是+=

$query = "SELECT * 
    FROM Tech AS T, Client AS C, Site AS S, Log AS L 
    WHERE T.TechID=L.TechID AND C.ClientID=L.ClientID AND S.SiteID=L.SiteID";
if($sort=="Tech")
   $query .= " ORDER BY T.TechName ASC, L.Time DESC";
else if($sort=="Client")
   $query .= " ORDER BY C.ClientName ASC, L.Time DESC";

【讨论】:

  • 天啊,我错过了 += 问题:s
  • @OlivierCoilland 乍一看我也是!认为它与使用不同的语言一起工作;)
  • 哦,还有DESC 而不是DSC
【解决方案3】:

您的问题出在WHERE 子句中。您需要使用AND 构造而不是逗号:

SELECT * 
FROM Tech AS T, Client AS C, Site AS S, Log AS L 
WHERE T.TechID=L.TechID AND C.ClientID=L.ClientID AND S.SiteID=L.SiteID

然而,更好的解决方案是使用连接:

SELECT * 
FROM Tech AS T
JOIN Client AS C on T.TechID=L.TechID
JOIN Site AS S on C.ClientID=L.ClientID
JOIN Log AS L on S.SiteID=L.SiteID

编辑:您得到near 0 at line 1,因为您使用+ 尝试连接字符串而不是. 运算符。当您使用+ 时,php 将这两个部分都转换为数字并将它们相加。由于您的字符串不联系号码,因此两者都转换为 0,因此结果为 0。因此,您的最终 SQL 只是 0。你可以通过print_r($query);查看它

EDIT2:感谢 Gerald Vesluis 注意到 ORDER BY 子句开头缺少空格。

【讨论】:

    【解决方案4】:

    + and += 添加数字,. and .= 附加字符串。

    结果数组中的字段名不包括表名。您应该引用(例如)$row['TechName'],而不是 $row['T.TechName']

    题外话

    混合 DB 访问和输出会产生过高的耦合。理想情况下,每个都将在单独的层中处理。您可以使用 PDO 或(在 PHP 5.4 及更高版本中)mysqli 启动此过程,并使用 foreach 对结果进行迭代,而不是显式调用属于 DB 结果类接口的任何方法。这个魔法是可能的,因为PDOStatement 和(自 PHP 5.4 起)mysqli_result 支持 Traversable 接口。

    &lt;br/&gt; 很少是semantic;使用更合适的东西,例如标题元素,或将样式应用于现有元素。

    &lt;th&gt; 不是&lt;td&gt; 的有效父级; &lt;tr&gt; 应该是父级并且应该使用&lt;th&gt; 代替 &lt;td&gt;

    虽然当分支由单个语句组成时括号是可选的,但将它们排除在外通常被认为是不好的样式,因为它有时会导致错误。

    虽然else if 在功能上等同于elseif,但它由运行时作为else 处理,if 作为主体:

    if (...) {
    } else {
        if (...) {
        }
    }
    

    elseif 是首选形式。

    如果$sort 有可能包含非字符串,== 甚至可以评估为TRUE (0 == 'Tech')。使用strict comparison (===) 确保将值作为字符串进行比较。

    应用各种建议的改动,你会得到类似的结果:

    # Future improvement: abstract each section into methods that are part of separate layers
    
    # Database access
    $statement = 'SELECT T.TechName, C.ClientName, S.SiteName, L.Time, L.Type 
        FROM Log AS L
          JOIN Tech AS T ON T.TechID=L.TechID
          JOIN Client AS C ON C.ClientID=L.ClientID
          JOIN Site AS S ON S.SiteID=L.SiteID';
    
    if ($sort === 'Tech') {
       $query .= ' ORDER BY T.TechName ASC, L.Time DESC';
    } elseif ($sort === 'Client') {
       $query .= ' ORDER BY C.ClientName ASC, L.Time DESC';
    }
    
    try {
        $data = $db->query($statement);
    } catch (PDOException $exc) {
        $data = array();
        # handle error appropriately: inform user that there was an internal error. Log the actual error and possibly notify the dev team.
        ...
    }
    
    # Output/User interface
    $fields = array('TechName' => 'Tech', 'ClientName' => 'Client', 'SiteName' => 'Site', 'Time' => 'Date and Time', 'Type' => 'Type');
    if ($data) {
        ?>
        <h3>Real-Time check in/check out</h3>
        <table>
          <thead>
            <tr><th><?php echo implode('</th><th>', $fields) ?></th></tr>
          </thead>
          <tbody>
            <?php foreach ($data as $row) { ?>
              <tr>
                <?php foreach ($fields as $field => $label) { ?>
                  <td><?php echo $row[$field] ?></td>
                <?php } ?>
              </tr>
            <?php } ?>
          </tbody>
        </table>
        <?php
    }
    

    【讨论】:

      【解决方案5】:

      我认为您需要在 $query 末尾放置一个空格,因为您将 order by 语句附加到它上面,中间没有任何空格。

      所以它看起来像这样:

      L.SiteIDORDERBY
      

      而不是这样:

      L.SiteID ORDER BY
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-28
        • 2023-02-13
        • 1970-01-01
        • 2018-07-01
        • 2019-08-17
        相关资源
        最近更新 更多