使用php从mySQL中的多个表中删除数据的方法和方法


Which method and how-to, for removing data from multiple tables in mySQL using php

我有一些代码,看起来像这样。您可以安全地假设之前已成功建立数据库连接,并且此处没有数据库通信问题:

if($value['caseKey'] === "Case01") {
    try {
        $stmt = $conn->prepare("SELECT * FROM tbl_Lodged, tbl_Search, tbl_Notes, tbl_Files,
        tbl_Case01_s1, tbl_Case01_s2, tbl_Case01_s3, tbl_Case01_s4, tbl_Case01_s5, tbl_Case01_s6, tbl_Case01_s7
        WHERE tbl_Lodged.uaID = tbl_Search.uaID AND tbl_Search.uaID = tbl_Notes.uaID
        AND tbl_Notes.uaID = tbl_Files.uaID AND tbl_Files.uaID = tbl_Case01_s1.uaID
        AND tbl_Case01_s1.uaID = tbl_Case01_s2.uaID AND tbl_Case01_s2.uaID = tbl_Case01_s3.uaID
        AND tbl_Case01_s3.uaID = tbl_Case01_s4.uaID AND tbl_Case01_s4.uaID = tbl_Case01_s5.uaID
        AND tbl_Case01_s5.uaID = tbl_Case01_s6.uaID AND tbl_Case01_s6.uaID = tbl_Case01_s7.uaID
        AND tbl_Lodged.uaID = :uaid");
        $stmt->bindValue(':uaid', $value['uaID']);
        $stmt->execute();
        $caseRes = $stmt->fetchAll();
    } catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
} else if($value['caseKey'] === "Case05") {
    try {
        $stmt = $conn->prepare("SELECT * FROM tbl_Lodged, tbl_Search, tbl_Notes, tbl_Files,
        tbl_Case05_s1, tbl_Case05_s2, tbl_Case05_s3, tbl_Case05_s4, tbl_Case05_s5
        WHERE tbl_Lodged.uaID = tbl_Search.uaID AND tbl_Search.uaID = tbl_Notes.uaID
        AND tbl_Notes.uaID = tbl_Files.uaID AND tbl_Files.uaID = tbl_Case05_s1.uaID
        AND tbl_Case05_s1.uaID = tbl_Case05_s2.uaID AND tbl_Case05_s2.uaID = tbl_Case05_s3.uaID
        AND tbl_Case05_s3.uaID = tbl_Case05_s4.uaID AND tbl_Case05_s4.uaID = tbl_Case05_s5.uaID
        AND tbl_Lodged.uaID = :uaid");
        $stmt->bindValue(':uaid', $value['uaID']);
        $stmt->execute();
        $caseRes = $stmt->fetchAll();
    } catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
} else ....... etc etc

对于选择与包含具有相应 uaID 的匹配 caseKey 的数据的表相关的所有内容,我可以很好地选择与表相关的所有内容,我想执行大致相同的操作,但我想执行DELETE而不是SELECT,所以我尝试了这个:

if($value['caseKey'] === "Case01") {
    try {
        $stmt = $conn->prepare("DELETE * FROM tbl_Lodged, tbl_Search, tbl_Notes, tbl_Files,
        tbl_Case01_s1, tbl_Case01_s2, tbl_Case01_s3, tbl_Case01_s4, tbl_Case01_s5, tbl_Case01_s6, tbl_Case01_s7
        WHERE tbl_Lodged.uaID = tbl_Search.uaID AND tbl_Search.uaID = tbl_Notes.uaID
        AND tbl_Notes.uaID = tbl_Files.uaID AND tbl_Files.uaID = tbl_Case01_s1.uaID
        AND tbl_Case01_s1.uaID = tbl_Case01_s2.uaID AND tbl_Case01_s2.uaID = tbl_Case01_s3.uaID
        AND tbl_Case01_s3.uaID = tbl_Case01_s4.uaID AND tbl_Case01_s4.uaID = tbl_Case01_s5.uaID
        AND tbl_Case01_s5.uaID = tbl_Case01_s6.uaID AND tbl_Case01_s6.uaID = tbl_Case01_s7.uaID
        AND tbl_Lodged.uaID = :uaid");
        $stmt->bindValue(':uaid', $value['uaID']);
        $stmt->execute();
    } catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
} else if($value['caseKey'] === "Case05") {
    try {
        $stmt = $conn->prepare("DELETE * FROM tbl_Lodged, tbl_Search, tbl_Notes, tbl_Files,
        tbl_Case05_s1, tbl_Case05_s2, tbl_Case05_s3, tbl_Case05_s4, tbl_Case05_s5
        WHERE tbl_Lodged.uaID = tbl_Search.uaID AND tbl_Search.uaID = tbl_Notes.uaID
        AND tbl_Notes.uaID = tbl_Files.uaID AND tbl_Files.uaID = tbl_Case05_s1.uaID
        AND tbl_Case05_s1.uaID = tbl_Case05_s2.uaID AND tbl_Case05_s2.uaID = tbl_Case05_s3.uaID
        AND tbl_Case05_s3.uaID = tbl_Case05_s4.uaID AND tbl_Case05_s4.uaID = tbl_Case05_s5.uaID
        AND tbl_Lodged.uaID = :uaid");
        $stmt->bindValue(':uaid', $value['uaID']);
        $stmt->execute();
    } catch(PDOException $e) { catchMySQLerror($e->getMessage()); }
} else ....... etc etc

我认为通过将SELECT更改为DELETE并删除$caseRes = $stmt->fetchAll();行,我会有一个相当好的解决方案。可悲的是,事实证明我错了。

但你可以看到我想做什么。我做了一些研究并发现了内部和外部版本的连接。我完全不明白它们,它们在我的脑海中没有意义,因为我基本上回到了 15 岁,记得我的木工老师谈论组装木箱的内部和外部连接。我倾向于以非常直观的表示形式看待事物,我引用的上述代码对我来说很有意义,因为它只是按 caseKey 过滤到下一阶段,即所有具有被调用的公共 uaID 的表都在以有点像传递包裹的方式进行操作 - 或者在这种情况下是 uaID。

不喜欢/理解连接,我想我必须手动完成每个相对表。痛苦,大量的代码和潜在的错误。我相信这可能就是所谓的代码气味?

阅读更多内容后,我在mySQL中发现了一种称为外键的东西。看来也许我可以在我的 php 中拥有这个:

try {
    $stmt = $conn->prepare("DELETE * FROM tbl_Lodged WHERE uaID = :uaid");
    $stmt->bindValue(':uaid', $value['uaID']);
    $stmt->execute();
} catch(PDOException $e) { catchMySQLerror($e->getMessage()); }

然后神奇地,任何具有特定uaID的东西都会被消除。

这是真的,还是我希望太多了?

如果是真的,我如何使用phpmyadmin版本3.4.11.1deb2 + deb7u1进行设置?我已经阅读了如何执行此操作,但我阅读的内容与我在phpmyadmin中看到的内容完全不同,并且在任何方面都不够接近使用。我是否应该放弃外键并重新尝试理解此操作的连接?

uaID在tbl_Lodged表中设置为 int(11)、自动递增、主键。它在表中的设置相同tbl_Search。它是其他相关表中的键,但不是主键。

提前感谢!

PS请记住,我不是代码忍者。不过我正在努力..!

PPS - 数据库正在使用InnoDB引擎。

感谢Ronald(下图),我应该澄清我想使用phpmyadmin设置FK功能,但我不想求助于必须使用phpmyadmin来实际删除任何内容。如果FK可以工作,设置FK的目的是让php可以通过cron作业自动完成。 Phpmyadmin 只是我设置和更改数据库的工具,而不是运行或管理它。我无法重新创建已经存在的表,但我希望可以修改现有表以适应使删除魔术起作用所需的表。

更新有谁知道如何从这里删除问题?

删除级联上的外键可能会有所帮助,如果您创建了引用 tbl_Lodged.uaID 的其他表。但我不确定你是不是这样。

mysql> CREATE TABLE tbl_Lodged(
-> uaID INT AUTO_INCREMENT, text_field VARCHAR(20), PRIMARY KEY(id)) ENGINE=InnoDB;
Query OK, 0 rows affected (0.08 sec)
mysql> CREATE TABLE tbl_Search(
-> id INT AUTO_INCREMENT, uaID INT, text_field VARCHAR(20), PRIMARY KEY(id),
-> FOREIGN KEY(uaID) REFERENCES tbl_Lodged(uaID) ON DELETE CASCADE) ENGINE=InnoDB;
Query OK, 0 rows affected (0.08 sec)

使用上面的示例,在phpmyadmin中执行sql语句"从uaID=1的tbl_Lodge中删除",您将删除tbl_Lodge中的1条记录以及tbl_Search中与uaID= 1匹配的所有记录

这就是你要找的吗?