错误的查询 - INNER JOIN

时间:2009-03-20 05:53:01

标签: php mysql

当我从SQL查询中打印出我的数据时,我收到了一堆未完成的索引警告,当我删除I​​NNER JOINS时,大多数警告都消失了。我不确定是什么导致了这个错误。

我的代码在这里:

<?php
    $id      = $_GET['id'];
    $sql     = "SELECT * FROM updates INNER JOIN clients ON updates.c_id = clients.c_id INNER JOIN pages ON updates.page = pages.p_id INNER JOIN projects ON updates.p_id = projects.p_id WHERE u_id='$id' LIMIT 1";
    echo $sql;
    $result  = mysql_query($sql) or die(mysql_error());
    $row     = mysql_fetch_assoc($result);

    // put update_id in hidden form and pass it to the next page
    $u_id = $row['u_id'];
?>
<h4>Viewing update for <i><? echo $row['fname'] ." ". $row['lname']  ?></i> for their <i><a href="<? echo $row['p_url']; ?>" title="View <? echo $row['p_title']; ?>"><? echo $row['p_title']; ?></a> project</i></h4>
<h4><b>Posted on: </b> <? echo $row['date_submitted'] = date("F j, Y, g:i a"); ?></h4>

知道我能做什么吗?我有INNER JOIN for CLIENTS的原因是因为“fname”和“lname”存储在那里

clients.c_id = updates.c_id

我所拥有的:“p_url”“p_title”那些存储在表PROJECTS中,它也是:

clients.c_id = projects.c_id

使用新问题进行编辑

我的代码在这里:

$sql     = "SELECT 
    updates.u_id AS u_id,
    updates.date_submitted AS date_submitted,
    updates.deadline AS deadline,
    updates.description AS description,
    updates.priority AS priority,
    pages.page_name AS page_name,
    clients.fname AS fname,
    clients.lname AS lname,
    projects.p_url AS p_url,
    projects.p_title AS p_title,
    FROM updates INNER JOIN clients ON updates.c_id = clients.c_id INNER JOIN pages ON updates.page = pages.p_id INNER JOIN projects ON updates.p_id = projects.p_id WHERE u_id='$id' LIMIT 1";

错误是:

  

不唯一的表/别名:'clients'

3 个答案:

答案 0 :(得分:2)

编辑回答:

啊,我错误地认为它与SQL索引有关。看起来它实际上是一个PHP错误,与您尝试打印不存在的数组元素有关。

对于包含$row$row['deadline']等)元素的所有打印件,您需要确保查询返回的实际列名称。如果没有名为“deadline”的列,则打印它的尝试将生成警告。


再次编辑:由于这个问题已经发生了变化,我想我会详细介绍一下。

首先,正如bobince指出的那样,你可以进行SQL注入。第一行应该是:

$id      = intval($_GET['id']);

如果$ id永远是一个整数,mysql_real_escape_string()如果它可以是一个字符串。

其次,SELECT *通常是不好的形式,特别是在连接的情况下。我不确切知道哪些表来自特定字段,但您的查询应该更像这样,您只选择实际要使用的字段:

$sql = "SELECT clients.fname, clients.lname, projects.p_url, projects.p_title, updates.date_submitted ".
        "FROM updates ".
            "INNER JOIN clients ON updates.c_id = clients.c_id ".
            "INNER JOIN pages ON updates.page = pages.p_id ".
            "INNER JOIN projects ON updates.p_id = projects.p_id ".
        "WHERE updates.u_id='$id' ".
        "LIMIT 1";

接下来,$u_id设置为与$id已有的完全相同的值,因此它是一种无意义的变量。

最后,在最后一行,你有:

<? echo $row['date_submitted'] = date("F j, Y, g:i a"); ?>

我不确定你期望做什么,但它会将date("F j, Y, g:i a");分配给$row['date_submitted'],然后最终打印出“true”或“1”或其他东西,这是可能不是你想要的。


最新问题:你们都尝试从客户端中选择,加入客户端,你们不能同时做到这两点,至少不给其中一个别名。

答案 1 :(得分:1)

我不认为这与SQL有任何关系(但我可能是错的)。你可以先看一下this线程。

答案 2 :(得分:0)

  

SELECT * FROM更新INNER JOIN客户端

当你'SELECT *'时,你会得到两个表中的每一列。由于列可以具有相同的名称,因此“*”自动生成的列名称将以表名为前缀。所以你的关联数组将包含如下索引:

updates.u_id
clients.c_id
...

因此,当您尝试使用未加前缀的列名称(例如“page_name”)访问阵列时,它会失败,因为该索引不存在。

您可以使用完整列名称('pages.page_name'),也可以通过以下方式明确指定自己的列名称:

SELECT updates.u_id AS u_id, pages.page_name AS page_name, ...
FROM updates JOIN client ...
  

U_ID = '$ ID'

哎呀,SQL注入漏洞。恭喜,您是本周的obligatory xkcd link的第1000名获胜者。

mysql_real_escape_string()是你的朋友。 (甚至更好:mysqli参数化查询。)

  

&LT ;? echo $ row ['deadline']; ?&GT;

哎呀,HTML注入漏洞。 htmlspecialchars()是你的朋友。