根据 POST 在 SQL 中搜索 - 加入 Table 中的变量

Searching in SQL per POST-Variable in joined Table

我尝试解决了一段时间,但没有找到解决方案。

我从一个充满移动设备的 table 中读取并列出它们,让用户可以根据移动设备名称和用户名搜索列表。

这是我的代码:

        SELECT
        *
    FROM
        tbl_mobdev
    LEFT JOIN
        tbl_mobdev_type ON mobdev_type_id = mobdev_type
    LEFT JOIN
        tbl_marke ON marke_id = mobdev_type_marke
    LEFT JOIN
        tbl_user ON tbl_user.id = mobdev_user
    WHERE
        CONCAT(tbl_marke.marke_name,' ',tbl_mobdev_type.mobdev_type_bezeichnung) LIKE '%".$_POST['marke_name']."%'
    AND
        CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'
    AND
        mobdev_aktiv = '1'
    ORDER BY
        ".$_GET['sort']." ".$_GET['sort2']."

只要 tbl_mobdev.mobdev_user 包含用户 ID,一切都会按预期工作,而 table 不包含用户 ID 的行将被排除。

有什么解决方案吗?

编辑:将 "filter" 放在 tbl_user 的 LEFT JOIN 中的解决方案不起作用。将在每一行中显示一个 SQL,如下所示的结果。 如果 LIKE 仅包含某些内容,则不会加入不匹配的结果,该行不会被过滤。

SELECT mobdev_id, mobdev_type_bezeichnung, marke_name, tbl_user.name AS  user_name, tbl_user.vorname AS user_vorname
FROM tbl_mobdev
LEFT JOIN tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN tbl_user ON tbl_user.id = mobdev_user
AND CONCAT( tbl_user.name, ' ', tbl_user.vorname ) LIKE '%%'
WHERE CONCAT( tbl_marke.marke_name, ' ', tbl_mobdev_type.mobdev_type_bezeichnung ) LIKE '%%'
AND mobdev_aktiv = '1'
ORDER BY marke_name ASC 
LIMIT 0 , 30

Edit2:将 SQL 设置为以下内容并没有改变行为。

SELECT mobdev_id, mobdev_type_bezeichnung, marke_name, tbl_user.name AS user_name, tbl_user.vorname AS user_vorname
FROM tbl_mobdev
LEFT JOIN tbl_mobdev_type ON mobdev_type_id = mobdev_type
LEFT JOIN tbl_marke ON marke_id = mobdev_type_marke
LEFT JOIN tbl_user ON tbl_user.id = mobdev_user
AND CONCAT( tbl_user.name, ' ', tbl_user.vorname ) LIKE '%G%'
WHERE CONCAT( tbl_marke.marke_name, ' ', COALESCE( tbl_mobdev_type.mobdev_type_bezeichnung, '' ) ) LIKE '%%'
AND mobdev_aktiv = '1'
ORDER BY marke_name ASC 
LIMIT 0 , 30

没有匹配 $_POST['user'] 的行仍然没有被过滤掉。

我上传了一张带有模糊名称的行为示例图片,左图是 Select 没有任何过滤器,右图是 Select 带有实际用户名(模糊,但是它与 mobdev_id '3'.

中的名称完全相同

http://fs5.directupload.net/images/160404/tmdbyzws.png

如您所见,其他五行仍然存在,只是没有连接。我希望它们完全消失,因为它们与过滤器不匹配。

Edit3:好吧,我现在做到了......遗憾的是使用 PHP 以一种非常肮脏的方式。我只是把代码放在这里,如果有人对此提出更好的解决方案,请告诉我。

$query = "
    SELECT
        mobdev_id,
        mobdev_type_bezeichnung,
        marke_name,
        tbl_user.name AS user_name,
        tbl_user.vorname AS user_vorname
    FROM
        tbl_mobdev
    LEFT JOIN
        tbl_mobdev_type ON mobdev_type_id = mobdev_type
    LEFT JOIN
        tbl_marke ON marke_id = mobdev_type_marke
    LEFT JOIN
        tbl_user ON tbl_user.id = mobdev_user
    WHERE
        CONCAT(tbl_marke.marke_name,' ',tbl_mobdev_type.mobdev_type_bezeichnung) LIKE '%".$_POST['marke_name']."%'
        ";
if($_POST['user'])
{
    $query .= "
        AND
            CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'
        ";
}
$query .= "
    AND
        mobdev_aktiv = '1'
    ORDER BY
        ".$_GET['sort']." ".$_GET['sort2']."
    ";

问题出在行

    CONCAT(tbl_user.name,' ',tbl_user.vorname) LIKE '%".$_POST['user']."%'

您在 tbl_user 上的 LEFT JOIN 将允许主查询 return 独立于该行中是否有值。但是,那个特定的 WHERE 子句行有效地覆盖了它;如果 tbl_user.name 或 tbl_user.vorname 为 null,则结果始终为 false。

如果我需要做那样的事情,我通常会把测试放在 JOIN 语句的 ON 子句中。这样它会过滤 JOINed table 存在的地方,但不会在它不存在的地方造成问题。

示例查询文本应确保 tbl_user 在需要时过滤,但在未指定任何内容时不过滤 -

SELECT
    md.mobdev_id, 
    mdt.mobdev_type_bezeichnung, 
    m.marke_name, 
    u.name AS  user_name, 
    u.vorname AS user_vorname
FROM
    tbl_mobdev md
        LEFT JOIN tbl_mobdev_type mdt
            ON mdt.mobdev_type_id = md.mobdev_type
        LEFT JOIN tbl_marke m
            ON m.marke_id = mdt.mobdev_type_marke
        LEFT JOIN tbl_user u
            ON u.id = md.mobdev_user
            AND CONCAT(u.name,' ',u.vorname) LIKE '%".$_POST['user']."%'
WHERE
    CONCAT(m.marke_name,' ',COALESCE(mdt.mobdev_type_bezeichnung,'')) 
            LIKE '%".$_POST['m.marke_name']."%'
    AND md.mobdev_aktiv = '1'
ORDER BY
    ".$_GET['sort']." ".$_GET['sort2']."

两个旁白 -

  • 正如 Rene M. 上面所说,这段代码是一个 SQL 注入漏洞。由于目前的应用,它可能是安全的,但我仍然不会推出它;有人拿走这个应用程序或代码片段,然后在没有进行全面审计的情况下将其转移到网上的可能性并不小,然后你就遇到了问题。练习正确操作 - 不要在代码中留下 SQL 注入漏洞。
  • 请为您的 table 名字取别名!为每个字段引用完整写出每个 table 名称的查询使其非常庞大。