如果表存在则删除表并创建它,如果不存在则创建它

我被难住了,我不知道该怎么做。

基本上我只想创建一个表,但如果它存在,就需要删除并重新创建,而不是截断,但如果它不存在,就创建它。

有人能帮忙吗?

294234 次浏览

只需使用DROP TABLE IF EXISTS:

DROP TABLE IF EXISTS `foo`;
CREATE TABLE `foo` ( ... );

如果有任何其他问题,请先尝试搜索MySQL文档

只要把DROP TABLE IF EXISTS `tablename`;放在你的CREATE TABLE语句之前。

如果表存在,该语句将删除该表,但如果表不存在,则不会抛出错误。

嗯…嗯。多年来,没有人提及一件微妙的事情。

尽管DROP TABLE IF EXISTS `bla`; CREATE TABLE `bla` ( ... );看起来很合理,但它会导致旧表已经消失而新表还没有创建的情况:一些客户端可能会在此时尝试访问主题表。

更好的方法是创建一个全新的表,并与旧表交换(表内容丢失):

CREATE TABLE `bla__new` (id int); /* if not ok: terminate, report error */
RENAME TABLE `bla__new` to `bla`; /* if ok: terminate, report success */
RENAME TABLE `bla` to `bla__old`, `bla__new` to `bla`;
DROP TABLE IF EXISTS `bla__old`;
  • 你应该检查CREATE ...的结果,不要继续 错误的情况,因为失败意味着其他线程没有完成 同样的脚本:要么是因为它在中间崩溃了,要么只是 还没做完呢——自己检查一下倒是个好主意 然后,你应该检查第一个RENAME ...的结果,不要这样做 continue 如果成功了:整个操作成功 完成;甚至,运行下一个RENAME ...可以(也将)是 如果另一个线程已经开始了相同的序列,则不安全 覆盖这种情况比不覆盖要好,参见下面的锁定注释)。
  • 第二个RENAME ...原子地替换表定义,参考 MySQL manual 李。< / > 最后,DROP ...只是清理旧表, 李。< / >

SELECT GET_LOCK('__upgrade', -1); ... DO RELEASE_LOCK('__upgrade');之类的东西包装所有语句允许只按顺序调用所有语句而不检查错误,但我不认为这是一个好主意:复杂性增加,MySQL中的锁定函数对于基于语句的复制是不安全的。

如果表数据应该在表定义升级中存活…对于一般情况,比较表定义以找出差异并生成正确的ALTER ...语句要复杂得多,这并不总是自动实现的,例如当列被重命名时。

你可以使用同样的方法处理视图,在这种情况下,CREATE/DROP TABLE仅仅转换为CREATE/DROP VIEW,而RENAME TABLE保持不变。事实上,你甚至可以把表变成视图,反之亦然

CREATE VIEW `foo__new` as ...; /* if not ok: terminate, report error */
RENAME TABLE `foo__new` to `foo`; /* if ok: terminate, report success */
RENAME TABLE `foo` to `foo__old`, `foo__new` to `foo`;
DROP VIEW IF EXISTS `foo__old`;

附注2: MariaDB用户应该对CREATE OR REPLACE TABLE/VIEW感到满意,它已经关心主题问题和它的细微之处

我需要删除一个表,并用视图中的数据重新创建。 我正在创建一个表的视图,这是我所做的:

DROP TABLE <table_name>;
CREATE TABLE <table_name> AS SELECT * FROM <view>;

上面的工作为我使用MySQL MariaDb。