我目前正在尝试使用C#从MySQL表中删除一行
我有两个非常基本的表:'head_doc'和'Doc_details'。 Head_doc包含一个名为id_doc的字段。 Doc_details还有一个名为id_doc的字段和其他各种字段
我正在尝试删除doc_details中可以在head_doc中找到的特定id_doc的所有详细信息。
这是我的查询,但我被告知DELETE查询的INNER JOIN是错误的编程。我怎样才能改变它?
DELETE h.*,d.*
FROM head_doc h
INNER JOIN
doc_details d
ON h.id_doc = d.id_doc
WHERE h.id_doc= id_doc;
答案 0 :(得分:2)
如果您只是想要删除doc_details中没有相应父记录(也称为孤立记录)的记录,那么这样做(这可以通过添加外键约束来避免。请注意以下内容):
delete
from doc_details
where id_doc not in (
select id_doc from head_doc
)
但是,如果你想要删除两个具有特定id的表中的所有记录,为了清楚起见,最好打破你的删除语句:
delete from doc_details where id_doc = <value>
delete from doc_head where id_doc = <value>
注意:如果您在子表上设置了外键约束,并且您想要删除父表中的记录,则数据库引擎将阻止您删除该记录。如果未首先删除子记录,则为父表。只要有可能,设置外键约束是一个好主意,以确保在删除父记录时不会在子表中显示孤立记录。
答案 1 :(得分:1)
不,在DELETE
语句中使用联接操作并不错。这是一种常见的模式。
我不确定是谁告诉你这是“糟糕的编程”,如果他们有任何理由告诉你。
对于来自多个表的删除行,MySQL可能会按照导致外键约束被违反的顺序执行操作(使用InnoDB表)。
例如,MySQL可能会尝试从head_doc
中删除一行,它会从doc_details
中删除相关的子行。
如果您使用涉及具有外键约束的InnoDB表的多表
DELETE
语句,则MySQL优化器可能会按照与其父/子关系不同的顺序处理表。在这种情况下,语句失败并回滚。相反,您应该从单个表中删除并依赖InnoDB提供的ON DELETE
功能,以便相应地修改其他表。
参考:http://dev.mysql.com/doc/refman/5.5/en/delete.html
或者,我们有时可以通过使用单独的语句从每个表中删除来解决该问题。
我们注意到,由于内部联接操作,问题中的查询只会从head_doc
中删除doc_details
中具有相关子行的行。如果没有任何子行,这将在head_doc
中留下行。这不一定是糟糕的编程。但这有点奇怪。
鉴于您要从两个表中删除行,您可能需要外部连接,因此即使{{1}中不存在匹配的子行,也要从head_doc
中删除行}}
doc_detais
鉴于你在两个表中都有 DELETE d.*
, h.*
FROM head_doc h
LEFT
JOIN doc_details d
ON d.id_doc = h.id_doc
WHERE h.id_doc = ?
,一个更简单的模式是使用两个单独的DELETE语句,首先从子表中删除,然后从父表中删除:
id_doc
如果 DELETE FROM doc_details WHERE id_doc = ?
DELETE FROM head_doc WHERE id_doc = ?
中要删除的行是由head_doc
列以外的其他条件标识的,则{{1>中不的列我们可以使用JOIN操作来识别子表中应该删除的行
e.g。首先,从子表中删除行(使用JOIN操作)
id_doc
然后,从父表中删除:
doc_details
总之,在DELETE中使用JOIN操作不一定是“编程错误”。我们需要注意一些警告。有时,使用连接操作是最好的方法。这实际上取决于你想要达到的目标。