Sql 在具有多个选择的删除中存在“外键不匹配”

Sql 在具有多个选择的删除中存在“外键不匹配”,sql,foreign-keys,Sql,Foreign Keys,我在SQL中使用了一个带有多个选择的删除,但是我得到了一个外键不匹配 SQL语句是: DELETE FROM tile_items WHERE tile_id IN (SELECT id FROM tiles WHERE house_id IN (SELECT id FROM houses

我在SQL中使用了一个带有多个选择的删除,但是我得到了一个外键不匹配

SQL语句是:

DELETE FROM tile_items 
WHERE tile_id IN (SELECT id 
                  FROM tiles 
                  WHERE house_id IN (SELECT id 
                                     FROM houses 
                                     WHERE owner <> 0 
                                       AND owner NOT IN (SELECT id FROM players)))
不确定是否需要,但以下是表格:

CREATE TABLE "tile_items" 
(
    "tile_id" INTEGER NOT NULL,
    "world_id" INTEGER NOT NULL DEFAULT 0,
    "sid" INTEGER NOT NULL,
    "pid" INTEGER NOT NULL DEFAULT 0,
    "itemtype" INTEGER NOT NULL,
    "count" INTEGER NOT NULL DEFAULT 0,
    "attributes" BLOB NOT NULL,
    UNIQUE ("tile_id", "world_id", "sid"),
    FOREIGN KEY ("tile_id") REFERENCES "tiles" ("id")
)

CREATE TABLE "tiles" 
(
    "id" INTEGER NOT NULL,
    "world_id" INTEGER NOT NULL DEFAULT 0,
    "house_id" INTEGER NOT NULL,
    "x" INTEGER NOT NULL,
    "y" INTEGER NOT NULL,
    "z" INTEGER NOT NULL,
    UNIQUE ("id", "world_id"),
    FOREIGN KEY ("house_id", "world_id") REFERENCES "houses" ("id", "world_id")
)
由于错误只引用了表tile_items和tiles,所以只发布了那些模式

希望有人能解释为什么我不能删除,但可以选择与此声明,谢谢

奇怪的是,同一条语句使用SELECT*FROM而不是DELETE FROM返回所有44条匹配记录

这并不奇怪。该错误报告外键问题。外键用于保证插入、更新和删除中的数据一致性。如果只选择数据,外键根本不重要

外键不匹配-平铺\u项引用平铺

此错误实际上不在delete语句上,而是在数据库及其外键上。您的语句是有效的,但DBMS允许无效的外键约束,并且仅在插入、更新或删除数据时报告这些约束。在我看来,如果DBMS事先阻止这种情况,那就更好了

在数据库中,您使用的是复合键。tiles表的唯一键是id,world_id,因此tile id只能与世界id组合使用。相同的tile id可以表示世界X中的一个tile和世界Y中的另一个tile。如果您不调用此列id,那会更好,因为它不会标识表中的记录。我建议对于仅是唯一标识列组的一部分的列使用非ID名称,如tile\u no或tile\u code。当然,这同样适用于房屋id

外键tile\u id引用tiles id

在这里,您需要说明tile\u items行所指的tiles行。但它是哪一个?仅磁贴ID不足以标识该表中的一行,您缺少世界ID。它必须是:

FOREIGN KEY (tile_id, world_id) REFERENCES tiles (id, world_id)

试试这个当你在谷歌搜索你的错误消息的答案时,你从中了解到了什么?嗯@philipxy,我认为我没有清楚正确地指定我要删除的字段,所以我得到了错误,但正如克斯特亚指出的,这是关于需要在级联上使用delete。因此,我将尝试在添加中更改我的表。将尽快发布结果。请在代码问题中给出一个剪切粘贴和可运行代码;示例输入,具有预期和实际输出,包括逐字错误消息;清晰的说明和解释。这包括您能给出的最少代码,即您显示为OK的代码,由您显示为not OK的代码扩展。调试基础。你的数据库管理系统是什么?您的tile_items FK声明是非法的标准/通用SQL,即使在运行select或delete之前,也没有PK/UNIQUE tile id可供其引用。你真的得到了一个select来运行吗?阅读FK声明。您应该始终使用正在使用的DBMS标记SQL问题。我想这是SQLite?谢谢你这么清楚。这里有两点。。。由于我使用BD Browser for SQLite,如中所述:如果表已经存在,并且您不想构建一个完整的脚本,那么您就走运了,SQLite不支持在生成表后添加外键,这使得我无法更改表,也无法创建另一个表,因为所有系统都已构建,我只是在写一个新剧本。总之,我无能为力。此外,我尝试在SELECT中使用复合键,但在DELETE中却没有。从平铺项目中删除平铺id,选择id中的世界id,从房子id中的世界id,选择id中的世界id,从拥有者0和所有者不在选择id中的房子中的世界id,我理解您不能更改表格平铺项目。。。以删除错误的约束并添加正确的约束。但是为什么你说你不能创建一个表呢?您应该能够使用ALTER TABLE tile_项重命名为重命名的_表;重命名现有表的步骤。然后创建表平铺_项。。。;使用正确的外键约束,然后插入到平铺_项中,从重命名的_表中选择*以复制其内容,最后删除重命名的_表。
FOREIGN KEY (tile_id, world_id) REFERENCES tiles (id, world_id)