2013-06-18 18 views
15

Sono su un database MySQL.Rilascia la chiave esterna solo se esiste

Lo sto facendo, ma non funziona.

ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`; 

Ho provato a mettere questo SE ESISTE ovunque potessi. Come si può verificare se una chiave esterna esiste prima di rilasciarla?

risposta

1

Quale database si sta utilizzando ??

Se SQL Server

if exists (select 1 from sys.objects where object_id = OBJECT_ID(N'[FKName]') AND  
parent_object_id = OBJECT_ID('TableName')) 
alter table TableName drop constraint FKName 
+0

Am utilizzando MySQL, ho cercato di mettere questo se esiste ovunque ho potuto. Come si può verificare se una chiave esterna esiste prima di rilasciarla? – Creditto

+0

Quale motore di archiviazione mysql stai usando? MYISAM o INNODB ?? Sei sicuro di non usare MYISAM? –

+0

AM usando il motore di memorizzazione INNODB in mysql, ho provato a mettere questo IF EXISTS ovunque potessi. Come si può verificare se una chiave esterna esiste prima di rilasciarla? – Creditto

7
IF EXISTS(
       SELECT * 
       FROM INFORMATION_SCHEMA.STATISTICS 
       WHERE INDEX_SCHEMA = DATABASE() 
        AND TABLE_NAME='myTable' 
        AND INDEX_NAME = 'myIndex') 
     THEN 

      ALTER TABLE `myTable` DROP FOREIGN KEY `myForeignKey`; 

      ALTER TABLE `myTable` DROP INDEX `myIndex` ; 

     END IF; 

Quando si crea un vincolo di chiave esterna, mysql crea automaticamente un indice sulla colonna di riferimento. L'esempio sopra mostra come controllare un indice in INFORMATION_SCHEMA, ma ci sono molte più informazioni da verificare nel information schema. Il nome dell'indice sembra indicare che è stato creato per un FK, quindi prima devi rilasciare l'FK, quindi rilasciare l'indice. Se crei di nuovo la chiave esterna, mysql creerà nuovamente l'indice. Ha bisogno di un indice per rafforzare l'integrità referenziale senza dover eseguire una scansione della tabella.

Se la tua intenzione era creare un nuovo indice che contenga la stessa colonna, dovresti prima creare quell'indice (con questa colonna, quella che sarà usata come FK, essendo la prima nella lista di colonne specificate per l'indice). Ora puoi aggiungere il tuo FK e mysql sarà felice di usare il nuovo indice senza crearne un altro.

Modifica: per visualizzare rapidamente gli indici è sufficiente eseguire SHOW INDEXES da myTable;

16

Se si vuole far cadere chiave esterna se esiste e non si desidera utilizzare le procedure si può fare in questo modo (per MySQL):

set @var=if((SELECT true FROM information_schema.TABLE_CONSTRAINTS WHERE 
      CONSTRAINT_SCHEMA = DATABASE() AND 
      TABLE_NAME  = 'table_name' AND 
      CONSTRAINT_NAME = 'fk_name' AND 
      CONSTRAINT_TYPE = 'FOREIGN KEY') = true,'ALTER TABLE table_name 
      drop foreign key fk_name','select 1'); 

prepare stmt from @var; 
execute stmt; 
deallocate prepare stmt; 

Se c'è chiave esterna mettiamo alter table affermazione in variabile e se non ci è stata inserita una dichiarazione fittizia. E poi lo eseguiamo.

10

Per maggiore riutilizzabilità, si vorrebbe effettivamente utilizzare una procedura memorizzata. Eseguire questo codice una volta sul vostro DB desiderato:

DROP PROCEDURE IF EXISTS PROC_DROP_FOREIGN_KEY; 
    DELIMITER $$ 
    CREATE PROCEDURE PROC_DROP_FOREIGN_KEY(IN tableName VARCHAR(64), IN constraintName VARCHAR(64)) 
    BEGIN 
     IF EXISTS(
      SELECT * FROM information_schema.table_constraints 
      WHERE 
       table_schema = DATABASE()  AND 
       table_name  = tableName  AND 
       constraint_name = constraintName AND 
       constraint_type = 'FOREIGN KEY') 
     THEN 
      SET @query = CONCAT('ALTER TABLE ', tableName, ' DROP FOREIGN KEY ', constraintName, ';'); 
      PREPARE stmt FROM @query; 
      EXECUTE stmt; 
      DEALLOCATE PREPARE stmt; 
     END IF; 
    END$$ 
    DELIMITER ; 

Successivamente, si può sempre sostituire questo:

ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`; 

con questo:

CALL PROC_DROP_FOREIGN_KEY('object', 'object_ibfk_1'); 

Lo script dovrebbe quindi funzionare senza problemi se object_ibfk_1 realtà esiste o no

Un sacco di credito a causa di: http://simpcode.blogspot.com.ng/2015/03/mysql-drop-foreign-key-if-exists.html

Problemi correlati