W jaki sposób można użyć ALTER do usunięcia kolumny w tabeli MySQL, jeśli taka kolumna istnieje?
Wiem, że mogę użyć ALTER TABLE my_table DROP COLUMN my_column
, ale jeśli my_column
nie istnieje , spowoduje to wyświetlenie błędu . Czy istnieje alternatywna składnia warunkowego usuwania kolumny?
Używam MySQL w wersji 4.0.18.
Odpowiedzi:
W przypadku MySQL nie ma żadnego: Żądanie funkcji MySQL .
W każdym razie pozwolenie na to jest prawdopodobnie bardzo złym pomysłem:
IF EXISTS
wskazuje, że wykonujesz destrukcyjne operacje na bazie danych o (dla Ciebie) nieznanej strukturze. Mogą zaistnieć sytuacje, w których jest to dopuszczalne w przypadku szybkiej i brudnej pracy lokalnej, ale jeśli masz pokusę, aby uruchomić takie oświadczenie na danych produkcyjnych (podczas migracji itp.), Bawisz się ogniem.Ale jeśli nalegasz, nie jest trudno po prostu najpierw sprawdzić istnienie w kliencie lub wyłapać błąd.
MariaDB obsługuje również następujące elementy począwszy od 10.0.2:
DROP [COLUMN] [IF EXISTS] col_name
to znaczy
ALTER TABLE my_table DROP IF EXISTS my_column;
Ale zapewne złym pomysłem jest poleganie na niestandardowej funkcji obsługiwanej tylko przez jedną z kilku rozwidleń MySQL.
źródło
MySQL nie obsługuje tego na poziomie języka. Oto obejście obejmujące metadane MySQL information_schema w wersji 5.0+, ale nie rozwiąże problemu w wersji 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;
Bardziej szczegółowe informacje napisałem w poście na blogu .
źródło
Wiem, że to stary wątek, ale istnieje prosty sposób obsługi tego wymagania bez korzystania z procedur składowanych. To może komuś pomóc.
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 ;
Mam nadzieję, że to komuś pomoże, tak jak mi (po wielu próbach i błędach).
źródło
Właśnie zbudowałem procedurę wielokrotnego użytku, która może pomóc w stworzeniu
DROP COLUMN
idempotencji:-- 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 ;
Stosowanie:
CALL drop_column_if_exists('my_table', 'my_column');
Przykład:
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
źródło
Odpowiedź Chase Seiberta działa, ale dodam, że jeśli masz kilka schematów, chcesz zmienić SELECT w ten sposób:
select * from information_schema.columns where table_schema in (select schema()) and table_name=...
źródło
Być może najprostszym sposobem rozwiązania tego problemu (który zadziała) jest:
UTWÓRZ nową_tabelę AS SELECT id, kol1, kol2, ... (tylko kolumny, które chcesz umieścić w ostatecznej tabeli) FROM my_table;
RENAME my_table TO old_table, new_table TO my_table;
DROP old_table;
Lub zachowaj old_table do wycofania w razie potrzeby.
To zadziała, ale klucze obce nie zostaną przeniesione. Będziesz musiał później ponownie dodać je do my_table; również klucze obce w innych tabelach, które odwołują się do my_table, będą musiały zostać naprawione (wskazano na nową my_table).
Powodzenia...
źródło
Możesz użyć tego skryptu, użyć swojej kolumny, schematu i nazwy tabeli
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;
źródło
Zdaję sobie sprawę, że ten wątek jest teraz dość stary, ale miałem ten sam problem. To było moje bardzo podstawowe rozwiązanie wykorzystujące MySQL Workbench, ale działało dobrze ...
x
DROPa
;wszystkie tabele, które miały tabelę, nie mają teraz żadnych tabel, które nie mają, wyświetlą błąd w dziennikach
wtedy możesz znaleźć / zamienić „upuść
a
”, zmienić na „DODAJ KOLUMNĘb
INT NULL” itp. i ponownie uruchomić całość ....trochę niezgrabne, ale w końcu otrzymujesz wynik końcowy i możesz kontrolować / monitorować cały proces i pamiętać o zapisywaniu skryptów sql na wypadek, gdybyś ich ponownie potrzebował.
źródło