2013-05-14 15 views
9

Mam tabeli z niżej strukturze:Mysql usunąć ograniczenie

CREATE TABLE `Lm_help` (
`id` int(10) NOT NULL AUTO_INCREMENT, 
`section` int(10) NOT NULL, 
`language` int(10) NOT NULL, 
`title` varchar(255) NOT NULL, 
`text` text NOT NULL, 
`timestamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, 
PRIMARY KEY (`id`), 
UNIQUE KEY `unique_help` (`section`,`language`), 
KEY `language_constraint` (`language`), 
CONSTRAINT `language_constraint` FOREIGN KEY (`language`) REFERENCES `Lm_languages` (`id`), 
CONSTRAINT `section_constraint` FOREIGN KEY (`section`) REFERENCES `Lm_help_sections` (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1 

muszę usunąć „unique_help” klucza, ale jestem coraz kluczową błąd wiązania obcego.

Z powodu tego błędu nie stanie usunąć niczego Wśród nich section_constraint, language_constraint, unique_help.

Poniżej są inne tabele, które odwołują się do tego:

CREATE TABLE `Lm_languages` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) NOT NULL, 
`code` varchar(255) NOT NULL, 
`status` int(11) DEFAULT NULL, 
`created_at` datetime NOT NULL, 
`updated_at` datetime NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 




CREATE TABLE `Lm_help_sections` (
`id` int(11) NOT NULL AUTO_INCREMENT, 
`name` varchar(255) NOT NULL, 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 
+0

Jaki błąd się masz dokładnie? –

+0

unique_help nie jest kluczem podstawowym, jest to unikalny indeks. Jaki błąd dostałeś? –

+0

Nie można upuścić indeksu „language_constraint”: potrzebne w klucz obcy – viv

Odpowiedz

19

Problemem jest to, że indeks unique_help (section, language) jest używany przez section_constraint klucz obcy. Nie można więc upuścić indeksu bez uprzedniego zniesienia ograniczenia.


Jednym ze sposobów rozwiązania tego jest upuść ograniczenie klucza obcego, potem spadek indeksu.

Następnie można dodać (prosty) indeks na (section) i ponownie utworzyć klucz obcy.

Wszystko to można zrobić w jednym stwierdzeniem:

ALTER TABLE Lm_help 
    DROP FOREIGN KEY section_constraint, -- drop the FK so 
    DROP INDEX unique_help,    -- the index can be dropped 
              -- and then 
    ADD INDEX section_IX (section),  -- add a new index 
    ADD CONSTRAINT section_FK    -- so the FK can be recreated 
     FOREIGN KEY (section) 
     REFERENCES Lm_help_sections (id) 
    ; 

Testowane na SQL-Fiddle


Poprawa

myliłem, nie ma potrzeby usuwania i odtwarzania przymus. Indeks może zostać pominięte, jak długo nowy indeks jest tworzony:

ALTER TABLE Lm_help 
    DROP INDEX unique_help, 
    ADD INDEX section_IX (section) 
    ; 

Testowane na SQL-Fiddle-2

+0

Dzięki , który działał, użyłem drop index section_constraint, to nie działało, ale upuść klucz obcy section_constraint pracował ... Czy możesz mi wyjaśnić, dlaczego ??? – viv

+0

To jest składnia (w MySQL), aby usunąć ograniczenia klucza obcego. –

2

As your error message suggests:

(...) w [Tabela wskazywanej przez klucz obcy] istnieje musi być indeksem , w którym kolumny z odniesieniem są wymienione w tej samej kolejności jako pierwsze kolumny w .

Musisz odnaleźć tabelę (tabelki) odsyłające i usunąć ograniczenia (klucze) klucza obcego z tej (tych) innych tabel.

Moje złe, zbyt wcześnie przeczytałem definicję stołu. Rzeczywisty problem jest the other way around:

MySQL wymaga indeksów kluczy obcych i kluczy odwołuje tak że klucz obcy kontrole mogą być szybko i nie wymagają skanowania tabeli.

Albo upuść section_constraint klucz obcy pierwszy, lub utworzyć nowy indeks na language przed upuszczeniem UNIQUE.

+0

Możesz rzucić okiem na strukturę innych tabel, które użyłem – viv

+0

Moja zła, zobacz mój nowy anwer. – RandomSeed

+0

NO problem jest ok, problem rozwiązany, dziękuję wszystkim ... – viv

6
ALTER TABLE Orders 
DROP FOREIGN KEY 'language_constraint'; 

ALTER TABLE Orders 
DROP FOREIGN KEY 'section_constraint'; 

PERFORM DELETE TUTAJ

ALTER TABLE Orders 
ADD CONSTRAINT `language_constraint` 
FOREIGN KEY (`language`) 
REFERENCES `Lm_languages` (`id`); 

ALTER TABLE Orders 
ADD CONSTRAINT `section_constraint` 
FOREIGN KEY (`section`) 
REFERENCES `Lm_help_sections` (`id`); 
+1

Dzięki tushar, który działał, ale nie mogę zaakceptować dwóch odpowiedzi ... :) – viv

+0

Nie ma problemu, cieszę się, że mój kod ci pomógł :) –

1

Oto procedura przechowywana, że ​​można zadzwonić do spadku obcy klucz przed wywołaniem sql tworzenia . I zmodyfikowane odpowiedzi na podobne pytanie o DROP PROCEDURA IF EXISTS Odpowiedział: https://stackoverflow.com/users/166161/thomas-paine

próbki rozmowy:

CALL DropForeignKey (DATABASE(), 'tablename', 'keyname'); 

procedury:

DELIMITER ; 

/* DROP_FOREIGN_KEY */ 
DROP PROCEDURE IF EXISTS DropForeignKey; 

DELIMITER // 

CREATE PROCEDURE DropForeignKey(
IN param_schema VARCHAR(100), 
IN param_table_name VARCHAR(100), 
IN param_constraint_name VARCHAR(100) 
) 

BEGIN 
    IF EXISTS(
    SELECT NULL FROM information_schema.TABLE_CONSTRAINTS 
    WHERE CONSTRAINT_NAME=param_constraint_name AND TABLE_NAME=param_table_name AND TABLE_SCHEMA = param_schema 
    ) 
    THEN 
     set @paramTable = param_table_name ; 

    set @ParamConstraintName = param_constraint_name ; 
    set @ParamSchema = param_schema; 
    /* Create the full statement to execute */ 
    set @StatementToExecute = concat('ALTER TABLE `',@ParamSchema,'`.`',@paramTable,'` DROP FOREIGN KEY `',@ParamConstraintName,'` '); 
    /* Prepare and execute the statement that was built */ 
    prepare DynamicStatement from @StatementToExecute ; 
    execute DynamicStatement ; 
    /* Cleanup the prepared statement */ 
    deallocate prepare DynamicStatement ; 

END IF; 
END // 

DELIMITER ; 
Powiązane problemy