2010-07-26 37 views
106

tôi nhận được thông báo lỗi này:Bogus ràng buộc khoá ngoại thất bại

ERROR 1217 (23000) tại dòng 40: không thể xóa hoặc cập nhật hàng mẹ: a ràng buộc khoá ngoại thất bại

... khi tôi cố gắng để thả một bảng:

DROP TABLE IF EXISTS `area`; 

... định nghĩa như thế này:

CREATE TABLE `area` (
    `area_id` char(3) COLLATE utf8_spanish_ci NOT NULL, 
    `nombre_area` varchar(30) COLLATE utf8_spanish_ci NOT NULL, 
    `descripcion_area` varchar(100) COLLATE utf8_spanish_ci NOT NULL, 
    PRIMARY KEY (`area_id`), 
    UNIQUE KEY `nombre_area_UNIQUE` (`nombre_area`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_spanish_ci; 

Điều thú vị là Tôi đã bỏ tất cả các bảng khác trong lược đồ có khóa ngoài chống lại area. Trên thực tế, cơ sở dữ liệu trống trừ bảng area.

Làm cách nào để có thể có hàng con nếu không có bất kỳ đối tượng nào khác trong cơ sở dữ liệu? Theo như tôi biết, InnoDB không cho phép các khóa ngoại trên các lược đồ khác, phải không?

(Tôi thậm chí có thể chạy một lệnh RENAME TABLE area TO something_else: -?)

+0

Có thể bảng đó là một phần của mối quan hệ Toàn vẹn tham chiếu trong một lược đồ khác không? –

+0

Tôi có một số bản sao khác của ứng dụng để luôn có thể. Tuy nhiên, cú pháp tôi sử dụng về cơ bản là 'CONSTRAINT fk_servicio_area1 FOREIGN KEY (area_id) vùng tham chiếu (area_id)', tức là, không có tên lược đồ nào trong tham chiếu bảng: -? –

Trả lời

99

Có hai khả năng:

  1. Có một bảng trong schema khác ("cơ sở dữ liệu "trong thuật ngữ mysql) có tham chiếu FK
  2. Từ điển dữ liệu nội bộ innodb không đồng bộ với sql một.

Bạn có thể xem bảng đó là (một trong số đó, dù sao) bằng cách thực hiện "SHOW ENGINE INNODB STATUS" sau khi lỗi không thành công.

Nếu hóa ra là trường hợp sau, tôi sẽ đổ và khôi phục toàn bộ máy chủ nếu bạn có thể.

MySQL 5.1 trở lên sẽ cung cấp cho bạn tên của bảng bằng FK trong thông báo lỗi.

+0

Tôi không còn có thể tạo lại vấn đề. Từ điển không đồng bộ hóa nổi bật như một lý do có thể. Tôi sẽ kiểm tra nó ngày và xem những gì 'SHOW ENGINE INNODB STATUS' báo cáo. –

+3

Cảm ơn bạn đã trả lời câu trả lời này! Tôi đã có một bảng nhiều người vẫn tham chiếu đến cái bàn mà chúng tôi không thể thả được, vì vậy tôi phải bỏ cái bàn đó trước. –

+0

tuyệt vời! chỉ cần cứu tôi giờ –

47

Disable chính nước ngoài kiểm tra

SET FOREIGN_KEY_CHECKS=0 
+62

Lệnh đúng xuất hiện là 'SET FOREIGN_KEY_CHECKS = 0' và nó sửa lỗi. Bạn có bất kỳ ý tưởng về lý do tại sao điều này là cần thiết? Các khóa ngoại được lưu trữ ngay cả sau khi các bảng đã biến mất? –

+1

Vâng để nói sự thật, tôi không có ý tưởng tại sao một vấn đề như vậy phát sinh, nhưng chắc chắn rằng bạn vô hiệu hóa kiểm tra chính mỗi khi bạn thực hiện một số thay đổi lớn hoặc cập nhật. Nó đã xảy ra với tôi nhiều lần, để lại cho tôi không ngủ trong nhiều ngày. –

+55

Hãy đảm bảo 'SET FOREIGN_KEY_CHECKS = 1;' sau khi bạn đã hoàn tất! –

0

Có thể bạn đã gặp lỗi khi làm việc với bảng này trước đây. Bạn có thể đổi tên bảng và thử xóa nó một lần nữa.

ALTER TABLE `area` RENAME TO `area2`; 
DROP TABLE IF EXISTS `area2`; 
121

Theo yêu cầu, bây giờ như một câu trả lời ...

Khi sử dụng MySQL Query Browser hoặc phpMyAdmin, dường như một kết nối mới được mở ra cho mỗi truy vấn (bugs.mysql.com/bug.php?id=8280), làm cho nó cần thiết để viết bài các câu lệnh thả trong một truy vấn, ví dụ:

SET FOREIGN_KEY_CHECKS=0; 
DROP TABLE my_first_table_to_drop; 
DROP TABLE my_second_table_to_drop; 
SET FOREIGN_KEY_CHECKS=1; 

Trường hợp SET FOREIGN_KEY_CHECKS=1 đóng vai trò như một biện pháp bảo mật bổ sung ...

+2

Đối với những người tạo ra một bãi chứa bằng cách sử dụng phpMyAdmin, có một tùy chọn "Vô hiệu hóa kiểm tra khóa nước ngoài" sẽ tự động thêm 'SET FOREIGN_KEY_CHECKS = 0;' vào đầu bãi chứa. – Mike

+0

Dường như phpMyAdmin đã triển khai tính năng đáng yêu này, giờ tôi đang đợi mysqlWorkbench làm như vậy! :) –

+0

@CodeMed FYI, tôi chấp nhận câu trả lời của MarkR vì nó cung cấp giải thích cho vấn đề có ý nghĩa - mặc dù tôi thừa nhận tôi không thể xác minh vì tôi chưa gặp vấn đề tương tự trong 6 năm tiếp theo, thậm chí không một lần . Câu trả lời này và trước đó cung cấp một giải pháp (tuyệt vời cho điều đó tốt) nhưng không thực sự giải quyết các câu hỏi chính nó và kể từ khi bạn chỉ có thể chấp nhận một câu trả lời tôi đã phải chọn. –

28

từ this blog:

Bạn có thể tạm thời tắt nước ngoài kiểm tra chính:

SET FOREIGN_KEY_CHECKS=0; 

Chỉ cần chắc chắn để khôi phục chúng khi bạn đang thực hiện rối tung xung quanh:

SET FOREIGN_KEY_CHECKS=1; 
+0

Câu trả lời hay như tôi đã phát triển trên địa phương :) – Adelin

+0

Câu trả lời hay nhất và hoạt động như một nét duyên dáng –

+0

Đó là giải pháp hợp lệ (tôi có thể xác nhận nó hoạt động) nhưng mục blog được liên kết không thực sự nói về kịch bản trong câu hỏi này (một cơ sở dữ liệu đã trống cho một bảng). –

6

hy vọng công việc của mình

SET foreign_key_checks = 0; DROP TABLE table name; SET foreign_key_checks = 1;

+0

Có, nó hoạt động, như nhiều lần nó đã được đề cập trước ;-) –

1

On Rails, người ta có thể làm như sau bằng cách sử dụng rails console:

connection = ActiveRecord::Base.connection 
connection.execute("SET FOREIGN_KEY_CHECKS=0;") 
-1

Không thể xóa hoặc cập nhật hàng mẹ:. Một ràng buộc khoá ngoại thất bại (table1user_role, CONSTRAINT [email protected]#5A6BD60 KEY NƯỚC NGOÀI (user_id) THAM KHẢO user (id))

Tôi đã làm gì trong hai bước đơn giản. đầu tiên tôi xóa hàng con trong bảng con như

mysql> xóa khỏi bảng2 trong đó role_id = 2 & & user_id = 20;

Query OK, 1 hàng bị ảnh hưởng (0,10 giây)

và bước thứ hai như xóa phụ huynh

xóa từ table1 nơi id = 20;

Query OK, 1 hàng bị ảnh hưởng (0,12 giây)

Bằng cách này tôi giải quyết các vấn đề có nghĩa Xóa Child sau đó Xóa mẹ

Tôi hy vọng bạn đã nhận nó. :)

+0

Vui lòng đọc lại câu hỏi. Bạn không thể xóa bảng không tồn tại. –

+0

Câu trả lời của tôi có liên quan nếu cả hai bảng tồn tại .. –

+0

trong trường hợp này, chúng tôi có thể loại bỏ ràng buộc khóa ngoài sau đó cố gắng xóa bảng. chúng ta có thể thả khóa ngoài như thế này ALTER TABLE DROP CONSTRAINT

0

tôi đã tìm thấy một giải pháp dễ dàng, xuất cơ sở dữ liệu, chỉnh sửa những gì bạn muốn chỉnh sửa trong trình chỉnh sửa văn bản, sau đó nhập nó. Đã thực hiện

+3

Đó là một giải pháp thú vị, có lẽ không nên thực sự xảy ra. Thay vào đó, bất cứ điều gì cần phải được thay đổi nên được thực hiện thông qua DBMS. Việc chỉnh sửa kết xuất cơ sở dữ liệu trong trình soạn thảo văn bản có vẻ giống như một đại lộ chín muồi cho các vấn đề. –

+1

Tôi thực sự không hiểu bạn đang làm gì. Dumping cơ sở dữ liệu, loại bỏ các 'CREATE TABLE' mã và tải dump một lần nữa ... sẽ không làm cho MySQL loại bỏ bảng. Và nếu bạn muốn khôi phục kết xuất trong cơ sở dữ liệu mới ... Nếu bạn muốn xóa sạch tất cả các bảng như tôi, một cơ sở dữ liệu mới được tạo sẽ bị trống. Nếu bạn muốn giữ một số bảng, cách giải quyết 'SET FOREIGN_KEY_CHECKS = 0' được đề cập ở khắp mọi nơi ở đây hoạt động tốt và đơn giản hơn; và có thể bạn không cần phải chỉnh sửa dump kể từ khi bản sao dữ liệu mới của bạn có thể không có từ điển dữ liệu không đồng bộ. –

Các vấn đề liên quan