Minhas pesquisas e experimentos ainda não produziram uma resposta, então espero alguma ajuda.
Estou modificando o arquivo de instalação de um aplicativo que nas versões anteriores não tinha uma coluna que desejo adicionar agora. Não quero adicionar a coluna manualmente, mas sim no arquivo de instalação e somente se a nova coluna ainda não existir na tabela.
A tabela é criada da seguinte maneira:
CREATE TABLE IF NOT EXISTS `#__comm_subscribers` (
`subscriber_id` int(11) NOT NULL auto_increment,
`user_id` int(11) NOT NULL default '0',
`subscriber_name` varchar(64) NOT NULL default '',
`subscriber_surname` varchar(64) NOT NULL default '',
`subscriber_email` varchar(64) NOT NULL default '',
`confirmed` tinyint(1) NOT NULL default '0',
`subscribe_date` datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (`subscriber_id`),
UNIQUE KEY `subscriber_email` (`subscriber_email`)
) ENGINE=MyISAM CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' COMMENT='Subscribers for Comm are stored here.';
Se eu adicionar o seguinte, abaixo da instrução create table, não tenho certeza do que acontecerá se a coluna já existir (e talvez esteja preenchida):
ALTER TABLE `#__comm_subscribers` ADD `subscriber_surname`;
ALTER TABLE `#__comm_subscribers` MODIFY `subscriber_surname` varchar(64) NOT NULL default '';
Então, tentei o seguinte, que encontrei em algum lugar. Isso não parece funcionar, mas não tenho certeza se o usei corretamente.
/*delimiter '//'
CREATE PROCEDURE addcol() BEGIN
IF NOT EXISTS(
SELECT * FROM information_schema.COLUMNS
WHERE COLUMN_NAME='subscriber_surname' AND TABLE_NAME='#__comm_subscribers'
)
THEN
ALTER TABLE `#__comm_subscribers`
ADD COLUMN `subscriber_surname` varchar(64) NOT NULL default '';
END IF;
END;
//
delimiter ';'
CALL addcol();
DROP PROCEDURE addcol;*/
Alguém tem uma boa maneira de fazer isso?
Respostas:
Observe que
INFORMATION_SCHEMA
não é compatível com MySQL anterior a 5.0. Nem os procedimentos armazenados são suportados antes do 5.0, portanto, se você precisa do MySQL 4.1, esta solução não é boa.Uma solução usada por estruturas que usam migrações de banco de dados é registrar em seu banco de dados um número de revisão para o esquema. Apenas uma tabela com uma única coluna e uma única linha, com um número inteiro indicando a revisão em vigor. Ao atualizar o esquema, aumente o número.
Outra solução seria apenas tentar o
ALTER TABLE ADD COLUMN
comando. Deve gerar um erro se a coluna já existir.Identifique o erro e desconsidere-o em seu script de atualização.
fonte
--force
opção, o que significa continuar mesmo se houver um erro. então, vá em frente. você só quer ter certeza de que não há instruções que NÃO queira que tenham sucesso se algo anterior tiver falhado.Aqui está uma solução de trabalho (recém-testada com MySQL 5.0 no Solaris):
À primeira vista, provavelmente parece mais complicado do que deveria, mas temos que lidar com os seguintes problemas aqui:
IF
instruções só funcionam em procedimentos armazenados, não quando executados diretamente, por exemplo, no cliente mysqlSHOW COLUMNS
não funciona em stored procedure, então tem que usar INFORMATION_SCHEMATABLE_SCHEMA=DATABASE()
.DATABASE()
retorna o nome do banco de dados atualmente selecionado.fonte
Se você estiver no MariaDB, não há necessidade de usar procedimentos armazenados. Basta usar, por exemplo:
Veja aqui
fonte
A maioria das respostas abordam como adicionar uma coluna com segurança em um procedimento armazenado. Eu tive a necessidade de adicionar uma coluna a uma tabela com segurança sem usar um proc armazenado e descobri que o MySQL não permite o uso de
IF Exists()
fora de um SP . Vou postar minha solução para que possa ajudar alguém na mesma situação.fonte
Outra maneira de fazer isso seria ignorar o erro com um
declare continue handler
:Eu acho que é mais limpo dessa forma do que com uma
exists
subconsulta. Especialmente se você tiver muitas colunas a adicionar e quiser executar o script várias vezes.mais informações sobre continuar manipuladores podem ser encontradas em http://dev.mysql.com/doc/refman/5.0/en/declare-handler.html
fonte
Estou usando o MySQL 5.5.19.
Gosto de ter scripts que você pode executar e executar novamente sem erros, especialmente onde os avisos parecem demorar, aparecendo novamente mais tarde enquanto estou executando scripts que não têm erros / avisos. No que diz respeito à adição de campos, escrevi um procedimento para torná-lo um pouco menos digitado:
O código para criar o procedimento addFieldIfNotExists é o seguinte:
Não escrevi um procedimento para modificar uma coluna com segurança, mas acho que o procedimento acima pode ser facilmente modificado para isso.
fonte
Peguei o sproc do OP e tornei-o reutilizável e independente de esquema. Obviamente, ainda requer MySQL 5.
fonte
Tentei apenas o script de procedimento armazenado. Parece que o problema são as
'
marcas em torno dos delimitadores. O MySQL Docs mostra que os caracteres delimitadores não precisam de aspas simples.Então você quer:
Ao invés de:
Funciona para mim :)
fonte
Se estiver executando isso em um script, você desejará adicionar a seguinte linha posteriormente para torná-lo reexecutável, caso contrário, obterá um erro de procedimento já existe.
fonte
A melhor maneira de adicionar a coluna em PHP> PDO:
Nota: a coluna da tabela não é repetível, o que significa que não precisamos verificar a existência de uma coluna, mas para resolver o problema verificamos o código acima:
por exemplo se funciona o alerta 1, senão 0, o que significa que a coluna existe! :)
fonte
Verifique se a coluna existe ou não no PDO (100%)
fonte
O procedimento de Jake https://stackoverflow.com/a/6476091/6751901 é muito simples e uma boa solução para adicionar novas colunas, mas com uma linha adicional:
você pode adicionar novas colunas mais tarde lá, e funcionará da próxima vez também:
fonte
Então, em $ res por ciclo, procure a chave de sua coluna Smth assim:
fonte
SHOW fields FROM __TABLE__NAME__ where field='_my_col_';
e, em seguida, verifique se o conjunto de resultados não está vazioAbaixo está o procedimento armazenado no MySQL para adicionar coluna (s) em diferentes tabelas em diferentes bancos de dados (s) se a coluna não existir em uma (s) tabela (s) de banco de dados (s) com as seguintes vantagens
fonte
fonte