问题 “如果不存在则创建表” - 如何检查模式?


是否有(或多或少)标准方法来检查是否有一个名为的表 mytable 存在,但它的架构是否类似于它应该是什么?我正在试验 H2数据库,和

CREATE TABLE IF NOT EXISTS mytable (....)

声明显然只检查表格 名称。如果有一个具有给定名称但具有不同模式的表,我希望得到一个例外。


9632
2018-03-19 12:15


起源

“一张名字相似的桌子”? “类似于它应该是什么样的架构”?对于一般的查询工具来说,这太模糊了。 - Thilo
+1因为我也想要这样的设施。不一定是数据库,而是工具/库。 - Thilo
@Thilo:它应该是“具有给定名称的表”,现在已修复。通过“类似于它应该是的模式”,我的意思是如果存在一个名为的表 mytable,它的模式必须等于我提供给查询的模式;否则我想得到某种错误。这是一个非常明确定义的查询,所以我想知道是否(如果不是,为什么不)有一种方法来表达它。实际上我很惊讶“IF NOT EXISTS”似乎只检查名称。 - Joonas Pulakka
好主意,想有类似的东西!但是,我从来没有听说过SQL构造能够做到这一点。 - Pekka 웃


答案:


SELECT  *
FROM    INFORMATION_SCHEMA.TABLES
WHERE   TABLE_NAME      = 'TableName'
    AND TABLE_SCHEMA    = 'public'

5
2017-09-03 23:42



你能详细说明吗?这是做什么的? - Joonas Pulakka
我做了它说它做的...它检查数据库中是否存在这样的表。该 INFORMATION_SCHEMA (有些)标准化,因此该语句适用于大多数数据库。 - Thomas Mueller
它也适用于MSSQL,但“默认”架构是“dbo” - isapir


CREATE TABLE IF NOT EXISTS ... 不是标准的SQL代码。

要做的是检查表是否已经在目录中。 例如,在Java中,您可以执行以下操作: connection.getMetaData().getTables(connection.getCatalog(), null, null, null)

有关详情,请参阅 javadoc java.sql.Connection


4
2018-03-19 12:47



但是,它不会检查架构(当然,使用MetaData,您可以自己检查,但这很乏味.Linux MetaData有一个可怕的API。)。 - Thilo


我不知道任何具有此功能的数据库本地。

没有使用它(滚动我自己的代码来做到这一点)但也许 Apache DdlUtils 可以帮助。

这是一件棘手的事情,特别是如果你想让它与不同的数据库供应商合作。 此外,对于传递模式需要多么相似,可能存在不同的意见。列名,列顺序,列类型,主键定义:当然。但是约束,约束的名称,表空间定义等等呢?


1
2018-03-19 12:44



我知道,这可能不像我想象的那么简单。尽管如此,鉴于这是对任何使用任何数据库的软件的检查 应该 做,令人惊讶的是,没有标准的解决方案。 - Joonas Pulakka


双重回答:

(a)应该通过应用程序的安装过程来确保表的存在,而不是应用程序本身在运行时。

(b)如果你真的认为你有正当理由偏离(a),你可以尝试查询目录,这是一个由表格组成的数据库,其结构或多或少是由SQL标准的INFORMATION_SCHEMA规定的。 。存在哪些表,它们具有哪些列,这些列是哪些数据类型,声明了哪些键等等,它们都在那里。


1
2018-03-19 19:32



许多应用程序不希望使用单独的安装程序/更新程序脚本来解决用户问题,并在内部管理其数据库方案。即使它们不创建表,在启动时检查表模式以断言应用程序的完整性也是有意义的(而不是在以后的某个时间内随机数据库错误失败)。我并不是说这种方法总是合适的,但在某些情况下需要它是有效的。 - Thilo
是的,我也认为虽然a)可能是通常的方式,但它类似于“C:驱动器的存在应该由应用程序的安装过程确保,而不是应用程序本身在运行时。“但严肃的应用程序不应该对环境做出任何假设。相反,它应该检查它。环境可以改变 - 迟早会发生变化。 - Joonas Pulakka