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 …