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

标签 php mysql join foreign-keys

我有一些代码效果非常好,如下所示。您可以安全地假设之前已成功建立数据库连接,并且此处不存在数据库通信问题:

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

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

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(); 行,我' d 有一个相当好的解决方案。遗憾的是,事实证明我错了。

但是你可以看到我正在尝试做什么。我做了一些研究并发现了内部和外部版本的连接。我根本不明白它们,它们在我的脑海中没有意义,因为我基本上回到了 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 设置为 int(11)、自动递增、tbl_Lodged 表中的主键。它在 tbl_Search 表中设置相同。它是其他相关表中的键,但不是主键。

提前致谢!

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

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

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

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

最佳答案

FOREIGN KEY ON DELETE CASCADE如果您引用 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 语句“delete from tbl_Lodge where uaID=1”,您将删除 tbl_Lodge 中的 1 条记录以及 tbl_Search 中与 uaID=1 匹配的所有记录

这就是你要找的吗?

关于php - 使用 php 从 mySQL 中的多个表中删除数据的方法和操作方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35714857/

相关文章:

MySQL : Problem in writing where clause according to scenario

php - 将 php 异常重新抛出到更高级别的 catch block 中

php - Magento 自定义支付方式:如何获取通过 Mage_Payment_Model_Method_Abstract::assignData() 设置的数据?

mysql - 重置 mysql 整数值

python - Flask-SQLAlchemy 的隔离级别

mysql - 为什么 mySQL 按 DESC 排序排名 9.98 高于 85.24?

PHP不会显示 "0"值字符串?

php - 在mysql字段中插入≠(不等于)

sql - 外连接/联合?- t/sql 查询

database - 我应该使用哪个连接?