MySQL, controleer of een kolom bestaat in een tabel met SQL

Ik probeer een query te schrijven die zal controleren of een specifieke tabel in MySQL een specifieke kolom heeft, en zo niet, maak deze dan aan. Anders niets doen. Dit is echt een gemakkelijke procedure in elke enterprise-class database, maar MySQL lijkt een uitzondering te zijn.

Ik dacht zoiets als

IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.COLUMNS 
           WHERE TABLE_NAME='prefix_topic' AND column_name='topic_last_update') 
BEGIN 
ALTER TABLE `prefix_topic` ADD `topic_last_update` DATETIME NOT NULL;
UPDATE `prefix_topic` SET `topic_last_update` = `topic_date_add`;
END;

zou werken, maar het mislukt slecht. Is er een manier?


Antwoord 1, autoriteit 100%

Dit werkt goed voor mij.

SHOW COLUMNS FROM `table` LIKE 'fieldname';

Met PHP zou het zoiets zijn als…

$result = mysql_query("SHOW COLUMNS FROM `table` LIKE 'fieldname'");
$exists = (mysql_num_rows($result))?TRUE:FALSE;

Antwoord 2, autoriteit 56%

@julio

Bedankt voor het SQL-voorbeeld. Ik heb de query geprobeerd en ik denk dat er een kleine wijziging nodig is om hem goed te laten werken.

SELECT * 
FROM information_schema.COLUMNS 
WHERE 
    TABLE_SCHEMA = 'db_name' 
AND TABLE_NAME = 'table_name' 
AND COLUMN_NAME = 'column_name'

Dat werkte voor mij.

Bedankt!


Antwoord 3, autoriteit 6%

Om iedereen te helpen die op zoek is naar een concreet voorbeeld van wat @Mchl beschreef, probeer iets als

SELECT * FROM information_schema.COLUMNS 
 WHERE TABLE_SCHEMA = 'my_schema' AND TABLE_NAME = 'my_table' 
 AND COLUMN_NAME = 'my_column'`

Als het false retourneert (nul resultaten), dan weet je dat de kolom niet bestaat.


Antwoord 4, autoriteit 4%

Ik gooide deze opgeslagen procedure samen met een begin uit de opmerkingen van @lain hierboven, best leuk als je het meer dan een paar keer moet aanroepen (en geen php nodig hebt):

delimiter //
-- ------------------------------------------------------------
-- Use the inforamtion_schema to tell if a field exists.
-- Optional param dbName, defaults to current database
-- ------------------------------------------------------------
CREATE PROCEDURE fieldExists (
OUT _exists BOOLEAN,      -- return value
IN tableName CHAR(255),   -- name of table to look for
IN columnName CHAR(255),  -- name of column to look for
IN dbName CHAR(255)       -- optional specific db
) BEGIN
-- try to lookup db if none provided
SET @_dbName := IF(dbName IS NULL, database(), dbName);
IF CHAR_LENGTH(@_dbName) = 0
THEN -- no specific or current db to check against
  SELECT FALSE INTO _exists;
ELSE -- we have a db to work with
  SELECT IF(count(*) > 0, TRUE, FALSE) INTO _exists
  FROM information_schema.COLUMNS c
  WHERE 
  c.TABLE_SCHEMA    = @_dbName
  AND c.TABLE_NAME  = tableName
  AND c.COLUMN_NAME = columnName;
END IF;
END //
delimiter ;

Werken met fieldExists

mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_option', NULL) //
Query OK, 0 rows affected (0.01 sec)
mysql> select @_exists //
+----------+
| @_exists |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)
mysql> call fieldExists(@_exists, 'jos_vm_product', 'child_options', 'etrophies') //
Query OK, 0 rows affected (0.01 sec)
mysql> select @_exists //
+----------+
| @_exists |
+----------+
|        1 |
+----------+

Antwoord 5, autoriteit 3%

Het volgende is een andere manier om het te doen met gewone PHP zonder de information_schema-database:

$chkcol = mysql_query("SELECT * FROM `my_table_name` LIMIT 1");
$mycol = mysql_fetch_array($chkcol);
if(!isset($mycol['my_new_column']))
  mysql_query("ALTER TABLE `my_table_name` ADD `my_new_column` BOOL NOT NULL DEFAULT '0'");

6, Autoriteit 3%

Selecteer gewoon column_name van informatie schema en zet het resultaat van deze vraag in variabele. Test vervolgens de variabele om te beslissen of tafel wijziging nodig heeft of niet.

P.S. Niet foget te TABLE_SCHEMA opgeven voor KOLOMMEN tafel ook.


7

Gooi ALTER TABLE / MODIFY KOLOMMEN of andere dergelijke tabel mod operaties binnen een transactie. Transacties zijn voor het kunnen terug te draaien een query falend beleid niet op veranderingen … het zal fout elke keer in een transactie.

Start gewoon een SELECT * query op de tafel en controleer of de kolom is er …

Other episodes