MySQLデータベースを使用しています。
私はこれをやっていますが、うまくいきません。
ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`;
可能であれば、このIF EXISTSを配置しようとしました。ドロップする前に外部キーが存在するかどうかを確認するにはどうすればよいですか?
外部キーが存在し、プロシージャを使用したくないの場合、外部キーを削除する場合は、この方法で実行できます(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;
外部キーがある場合、変数にalter tableステートメントを配置し、ない場合はダミーステートメントを配置します。そして、それを実行します。
再利用性を高めるには、実際にストアドプロシージャを使用する必要があります。目的のDBでこのコードを1回実行します。
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 ;
その後、いつでもこれを置き換えることができます。
ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`;
これとともに:
CALL PROC_DROP_FOREIGN_KEY('object', 'object_ibfk_1');
スクリプトは、object_ibfk_1
は実際に存在するかどうか。
多くのクレジット: http://simpcode.blogspot.com.ng/2015/03/mysql-drop-foreign-key-if-exists.html
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;
外部キー制約を作成すると、mysqlは参照列にインデックスを自動的に作成します。上記の例は、INFORMATION_SCHEMAでインデックスをチェックする方法を示していますが、 情報スキーマ でチェックアウトするためのより多くの情報があります。インデックス名は、FK用に作成されたことを示しているようです。そのため、最初にFKを削除してから、インデックスを削除する必要があります。外部キーを再度作成すると、mysqlはインデックスを再度作成します。テーブルスキャンを行わずに参照整合性を適用するには、インデックスが必要です。
同じ列を含む新しいインデックスを作成する場合は、最初にそのインデックスを作成する必要があります(この列では、FKとして使用されるインデックスが、インデックス)。これでFKを追加し直すことができ、mysqlは別のインデックスを作成せずに新しいインデックスを使用できるようになります。
編集:インデックスをすばやく表示するには、SHOW INDEXES FROM myTableを実行するだけです。
Mariadb 10.1.26(新しいMysql)の現在のバージョンでは、クエリは機能します。
キー:MUL
ALTER TABLE `object` DROP FOREIGN KEY IF EXISTS `object_ibfk_1`;
DESC `object`;
キー:<NULL>
どのデータベースを使用していますか??
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
DROP FOREIGN KEY IF EXISTS
の前のMySQLおよびMariaDBバージョンにはないv10.1.4
の回避策を次に示します。 FOREIGN KEY
の存在に依存する必要がある他のすべてのステートメントにも使用できます(たとえば、以下の例のようにSELECT "info: foreign key exists."
の場合)。
-- DROP FOREIGN KEY IF EXISTS
SELECT
COUNT(*)
INTO
@FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS
FROM
`information_schema`.`table_constraints`
WHERE
`table_schema` = 'my_database'
AND `table_name` = 'my_table'
AND `constraint_name` = 'my_foreign_key'
AND `constraint_type` = 'FOREIGN KEY'
;
-- SELECT @FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS;
SET @statement := IF(
@FOREIGN_KEY_my_foreign_key_ON_TABLE_my_table_EXISTS > 0,
-- 'SELECT "info: foreign key exists."',
'ALTER TABLE my_table DROP FOREIGN KEY my_foreign_key',
'SELECT "info: foreign key does not exist."'
);
PREPARE statement FROM @statement;
EXECUTE statement;