Frage

Wie kann ALTER verwendet werden, um eine Spalte in einer MySQL-Tabelle zu löschen, wenn diese Spalte vorhanden ist?

Ich weiß, ich kann ALTER TABLE my_table DROP COLUMN my_column verwenden, aber das wird einen Fehler aus, wenn my_column existiert nicht. Gibt es alternative Syntax für Fallenlassen der Spalte bedingt?

Ich bin mit MySQL Version 4.0.18.

War es hilfreich?

Lösung

Für MySQL gibt es keine: MySQL Feature Request .

Unter Berücksichtigung Dies ist wohl eine wirklich schlechte Idee, trotzdem: IF EXISTS zeigt an, dass Sie auf einer Datenbank mit (für Sie) unbekannte Struktur zerstörende Operationen ausführen. Es Situationen geben kann, wo dies für eine schnelle und unsaubere akzeptabel ist Arbeit vor Ort, aber wenn Sie gereizt werden, eine solche Aussage gegen Produktionsdaten ausgeführt werden (in einer Migration etc.), sind Sie mit dem Feuer zu spielen.

Aber wenn Sie darauf bestehen, es ist nicht schwierig, einfach die Existenz überprüfen Sie zuerst in dem Client oder den Fehler zu fangen.

MariaDB unterstützt auch die folgenden beginnend mit 10.0.2:

  

DROP [COLUMN] [IF EXISTS] col_name

i. e.

  

ALTER TABLE my_table DROP IF my_column VORHANDEN;

Aber es ist wohl eine schlechte Idee, auf einem Nicht-Standard-Feature von nur einem von mehreren Gabeln von MySQL unterstützt zu verlassen.

Andere Tipps

Es gibt keine Sprache-Level-Support für diese in MySQL. Hier ist eine Methode, die beinhaltet MySQL information_schema Meta-Daten in 5.0+, aber es wird nicht Ihr Problem in 4.0.18 Adresse.

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;

ich einige detailliertere Informationen in einem Blog-Eintrag geschrieben .

Ich weiß, das ist ein alter Thread, aber es ist ein einfacher Weg, um diese Anforderung zu handhaben, ohne Verwendung von gespeicherten Prozeduren. Dies kann jemand helfen.

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 ;

Hope, das hilft jemand, wie es mir angetan hat (nach viel Versuch und Irrtum).

Ich baute gerade ein wiederverwendbares Verfahren, das DROP COLUMN Idempotent helfen können machen:

-- 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 ;

Verbrauch:

CALL drop_column_if_exists('my_table', 'my_column');

Beispiel:

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

Chase Seibert Antwort funktioniert, aber ich würde hinzufügen, dass, wenn Sie mehrere Schemen haben Sie die SELECT verändern wollen also:

select * from information_schema.columns where table_schema in (select schema()) and table_name=...

Ich weiß, dieser Thread jetzt ziemlich alt, aber ich war mit dem gleichen Problem. Dies war meine sehr einfache Lösung, um die MySQL Workbench verwenden, aber es funktionierte gut ...

  1. einen neuen SQL-Editor erhalten und SHOW TABLES ausführen, um eine Liste Ihrer Tabellen erhalten
  2. Wählen Sie alle Zeilen und in der Zwischenablage (nicht börsennotierte) aus dem Kontextmenü kopieren wählen
  3. fügen Sie die Liste der Namen in einem anderen Editor Tab
  4. schreiben Sie Ihre Abfrage, dh ALTER TABLE x DROP a;
  5. Sie etwas kopieren und einfügen, so dass Sie mit separater Abfrage für jede Tabelle
  6. am Ende
  7. Umschalten, ob die Werkbank stoppen soll, wenn ein Fehler auftritt
  8. Hit ausführen und schauen Sie durch das Ausgabeprotokoll

alle Tabellen, die die Tabelle jetzt hatten oder nicht alle Tabellen, die nicht haben, einen Fehler in den Protokollen

gezeigt

, dann können Sie Suchen / Ersetzen 'drop a' ändern zu 'COLUMN b INT NULL ADD' usw. und das Ganze wieder laufen ....

ein bisschen klobig, aber schließlich erhalten Sie das Ergebnis Ende und Sie können / steuern den gesamten Prozess überwachen und erinnern Sie sich, SQL-Skripts zu speichern, falls Sie sie wieder benötigen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top