我遇到了标题中提到的错误,这里是我的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”附近使用正确的语法
答案 0 :(得分:4)
无法看到零来自哪里..
但是,在您将ORDER BY附加到查询的行中,您错过了一个空格。
在原始$query
的末尾添加空格,或在$query +=
另外,对于降序,它应该是DESC
而不是DSC
此外,+ =应该是。= for PHP
答案 1 :(得分: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
条款开头注意到缺少的空间。
答案 2 :(得分:3)
而不是逗号,
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";
答案 3 :(得分:1)
结果数组中的字段名称不包含表名。您应该引用(例如)$row['TechName']
,而不是$row['T.TechName']
。
混合DB访问和输出会产生过高的耦合。理想情况下,每个都将在不同的层中处理。您可以使用PDO或(在PHP 5.4及更高版本中)mysqli启动此过程,并在结果上使用foreach
进行迭代,而不是显式调用作为DB结果类接口一部分的任何方法。这种魔力是可能的,因为PDOStatement
和(从PHP 5.4开始)mysqli_result
支持Traversable
接口。
<br/>
很少semantic;使用更合适的东西,例如标题元素,或将样式应用于现有元素。
<th>
不是<td>
的有效父级; <tr>
应为父级,<th>
应使用代替 <td>
。
虽然括号是可选的,但是当一个分支由一个语句组成时,它通常被认为是不好的风格,因为它偶尔会导致错误。
虽然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
}
答案 4 :(得分:0)
我认为你需要在$ query的末尾添加一个空格,因为你要将order by语句附加到它上面而没有任何空格。
所以它看起来像这样:
L.SiteIDORDERBY
而不是这样:
L.SiteID ORDER BY