Bagaimana ALTER dapat digunakan untuk menjatuhkan kolom di tabel MySQL jika kolom itu ada?
Saya tahu saya bisa menggunakan ALTER TABLE my_table DROP COLUMN my_column
, tapi itu akan menimbulkan kesalahan jika my_column
tidak ada. Apakah ada sintaks alternatif untuk menjatuhkan kolom secara kondisional?
Saya menggunakan MySQL versi 4.0.18.
Jawaban:
Untuk MySQL, tidak ada: Permintaan Fitur MySQL .
Membiarkan ini bisa dibilang ide yang sangat buruk, bagaimanapun:
IF EXISTS
menunjukkan bahwa Anda menjalankan operasi destruktif pada database dengan (kepada Anda) struktur yang tidak diketahui. Mungkin ada situasi di mana ini dapat diterima untuk pekerjaan lokal yang cepat dan kotor, tetapi jika Anda tergoda untuk menjalankan pernyataan seperti itu terhadap data produksi (dalam migrasi dll.), Anda bermain-main dengan api.Tetapi jika Anda bersikeras, tidak sulit untuk hanya memeriksa keberadaannya terlebih dahulu di klien, atau untuk menemukan kesalahannya.
MariaDB juga mendukung yang berikut, dimulai dengan 10.0.2:
DROP [COLUMN] [IF EXISTS] col_name
yaitu
ALTER TABLE my_table DROP IF EXISTS my_column;
Tapi bisa dibilang ide yang buruk untuk mengandalkan fitur non-standar yang hanya didukung oleh satu dari beberapa fork MySQL.
sumber
Tidak ada dukungan tingkat bahasa untuk ini di MySQL. Berikut adalah solusi yang melibatkan meta-data MySQL information_schema di 5.0+, tetapi itu tidak akan mengatasi masalah Anda di 4.0.18.
drop procedure if exists schema_change; delimiter ';;' create procedure schema_change() begin /* delete columns if they exist */ if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column1') then alter table table1 drop column `column1`; end if; if exists (select * from information_schema.columns where table_schema = schema() and table_name = 'table1' and column_name = 'column2') then alter table table1 drop column `column2`; end if; /* add columns */ alter table table1 add column `column1` varchar(255) NULL; alter table table1 add column `column2` varchar(255) NULL; end;; delimiter ';' call schema_change(); drop procedure if exists schema_change;
Saya menulis beberapa informasi yang lebih rinci dalam posting blog .
sumber
Saya tahu ini adalah utas lama, tetapi ada cara sederhana untuk menangani persyaratan ini tanpa menggunakan prosedur tersimpan. Ini dapat membantu seseorang.
set @exist_Check := ( select count(*) from information_schema.columns where TABLE_NAME='YOUR_TABLE' and COLUMN_NAME='YOUR_COLUMN' and TABLE_SCHEMA=database() ) ; set @sqlstmt := if(@exist_Check>0,'alter table YOUR_TABLE drop column YOUR_COLUMN', 'select ''''') ; prepare stmt from @sqlstmt ; execute stmt ;
Semoga ini membantu seseorang, seperti yang saya lakukan (setelah banyak trial and error).
sumber
Saya baru saja membuat prosedur yang dapat digunakan kembali yang dapat membantu membuat
DROP COLUMN
idempoten:-- column_exists: DROP FUNCTION IF EXISTS column_exists; DELIMITER $$ CREATE FUNCTION column_exists( tname VARCHAR(64), cname VARCHAR(64) ) RETURNS BOOLEAN READS SQL DATA BEGIN RETURN 0 < (SELECT COUNT(*) FROM `INFORMATION_SCHEMA`.`COLUMNS` WHERE `TABLE_SCHEMA` = SCHEMA() AND `TABLE_NAME` = tname AND `COLUMN_NAME` = cname); END $$ DELIMITER ; -- drop_column_if_exists: DROP PROCEDURE IF EXISTS drop_column_if_exists; DELIMITER $$ CREATE PROCEDURE drop_column_if_exists( tname VARCHAR(64), cname VARCHAR(64) ) BEGIN IF column_exists(tname, cname) THEN SET @drop_column_if_exists = CONCAT('ALTER TABLE `', tname, '` DROP COLUMN `', cname, '`'); PREPARE drop_query FROM @drop_column_if_exists; EXECUTE drop_query; END IF; END $$ DELIMITER ;
Pemakaian:
CALL drop_column_if_exists('my_table', 'my_column');
Contoh:
SELECT column_exists('my_table', 'my_column'); -- 1 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0 CALL drop_column_if_exists('my_table', 'my_column'); -- success SELECT column_exists('my_table', 'my_column'); -- 0
sumber
Jawaban Chase Seibert berfungsi, tetapi saya akan menambahkan bahwa jika Anda memiliki beberapa skema, Anda ingin mengubah SELECT sebagai:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
sumber
Mungkin cara paling sederhana untuk menyelesaikan ini (yang akan berhasil) adalah:
BUAT tabel_baru SEBAGAI PILIH id, col1, col2, ... (hanya kolom yang benar-benar Anda inginkan di tabel akhir) DARI tabel_saya;
GANTI NAMA tabel_saya KE tabel_ lama, tabel_baru KE tabel_saya;
DROP old_table;
Atau pertahankan old_table untuk rollback jika perlu.
Ini akan berfungsi tetapi kunci asing tidak akan dipindahkan. Anda harus menambahkannya kembali ke my_table nanti; juga kunci asing di tabel lain yang mereferensikan my_table harus diperbaiki (menunjuk ke my_table baru).
Semoga berhasil...
sumber
Anda dapat menggunakan skrip ini, menggunakan kolom, skema dan nama tabel Anda
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'TableName' AND COLUMN_NAME = 'ColumnName' AND TABLE_SCHEMA = SchemaName) BEGIN ALTER TABLE TableName DROP COLUMN ColumnName; END;
sumber
Saya menyadari utas ini sudah cukup tua sekarang, tetapi saya mengalami masalah yang sama. Ini adalah solusi paling dasar saya menggunakan MySQL Workbench, tetapi berfungsi dengan baik ...
x
DROPa
;setiap tabel yang memiliki tabel sekarang tidak memiliki tabel yang tidak akan menampilkan kesalahan di log
maka Anda dapat menemukan / mengganti 'drop
a
' mengubahnya menjadi 'ADD COLUMNb
INT NULL' dll dan jalankan semuanya lagi ....agak kikuk, tetapi akhirnya Anda mendapatkan hasil akhirnya dan Anda dapat mengontrol / memantau seluruh proses dan ingat untuk menyimpan skrip sql jika Anda membutuhkannya lagi.
sumber