【问题标题】:Postgresql: how to create table only if it does not already exist?Postgresql:仅当表不存在时如何创建表?
【发布时间】:2010-09-30 22:17:50
【问题描述】:

在 Postgresql 中,只有在表不存在的情况下,我如何才能创建创建表的条件?

代码示例赞赏。

【问题讨论】:

  • 如果您的表定义与现有表定义不匹配,您希望发生什么?报错,修改表,什么都不做?一些上下文会有所帮助。

标签: sql database postgresql


【解决方案1】:

我不确定它是什么时候添加的,但为了完整起见,我想指出,在 9.1 版(可能之前)中可以使用IF NOT EXISTS。 IF NOT EXISTS 只会在表不存在时创建表。

例子:

CREATE TABLE IF NOT EXISTS users.vip
(
  id integer
)

如果表不存在,这将在架构 users 中创建一个名为 vip 的表。

Source

【讨论】:

  • 在9.1中已经实现。
【解决方案2】:
create or replace function update_the_db() returns void as
$$
begin

    if not exists(select * from information_schema.tables 
        where 
            table_catalog = CURRENT_CATALOG and table_schema = CURRENT_SCHEMA
            and table_name = 'your_table_name_here') then

        create table your_table_name_here
        (
            the_id int not null,
            name text
        );

    end if;

end;
$$
language 'plpgsql';

select update_the_db();
drop function update_the_db();

【讨论】:

  • 这不考虑当前模式,即它会检查表是否存在于any 模式中,如果存在则不在当前模式中创建它。
  • 我在一个相关问题上发布了一个very similar, but somewhat simpler version。刚刚找到这个。
【解决方案3】:

只需创建表,不用担心它是否存在。如果它不存在,它将被创建;如果它确实存在,则不会修改该表。您可以随时检查 SQL 查询的返回值,以查看执行 create 语句时表是否存在。

【讨论】:

  • 大多数时候你确实不必担心。当创建发生在事务内部时,它会导致事务中止。
  • 就个人而言,我认为这种类型的答案/思维会鼓励不良做法。如果我预计该表可能存在,则必须对其进行测试,而不是检查错误情况。也许在 2011 年,范式的运作方式会有所不同?现在,当尝试创建一个已经存在的表时,dbms 会创建一个错误。
【解决方案4】:

我认为检查 pg_class 表可能会对您有所帮助,类似这样:

SELECT COUNT (relname) as a FROM pg_class WHERE relname = 'mytable'

if a = 0 then (CREATE IT)

问候。

【讨论】:

    【解决方案5】:

    这是一个老问题。我只是带回来建议另一个答案。注意:其他更好的答案已经存在,这仅用于教育目的。

    最简单的方法就是照别人说的去做;如果要保留现有数据,请执行 CREATE TABLE;如果您想要新创建的表,请执行 DROP IF EXISTS 然后执行 CREATE TABLE。

    另一种选择是查询系统表是否存在并从那里继续。

    SELECT true FROM pg_tables WHERE tablename = <table> [AND schemaname = <schema>];
    

    使用中:

    -- schema independent:
    SELECT true FROM pg_tables WHERE tablename = 'foo';
    
    -- schema dependent:
    SELECT true FROM pg_tables WHERE tablename = 'foo' AND schemaname = 'bar';
    

    如果匹配,您将获得一个真值,否则它应该返回一个空数据集。您可以使用该值来确定是否需要执行 CREATE TABLE。

    【讨论】:

    • 值得注意的是,如果您使用AND schemaname = &lt;schema&gt;,诸如临时表之类的东西将会存在,但会放在不同的架构中......
    【解决方案6】:

    如果您运行的是 Postgresql 9.1+,Skalli 给出了最佳答案。

    如果您像我一样需要使用 Postgresql 8.4 执行此操作,您可以使用带有“duplicate_table”异常捕获的函数。

    这将在表存在时忽略生成的错误并继续生成其他错误。

    这是一个在 Postgresql 8.4.10 上工作的示例:

    CREATE FUNCTION create_table() RETURNS VOID AS
    $$
    BEGIN
        CREATE TABLE my_table_name(my_column INT);
    EXCEPTION WHEN duplicate_table THEN
        -- Do nothing
    END;
    $$
    LANGUAGE plpgsql;
    

    【讨论】:

      【解决方案7】:

      我用来检查表是否存在的方法(Java & PostgreSQL) 在创建它之前。我希望这可以帮助别人。 这里没有实现create table部分,只是检查一下是否 一个表已经存在。 传入与数据库的连接和 tableName,它应该返回是否 表不存在。

      public boolean SQLTableExists(Connection connection, String tableName) {
          boolean exists = false;
      
          try {
              Statement stmt = connection.createStatement();
              String sqlText = "SELECT tables.table_name FROM information_schema.tables WHERE table_name = '" + tableName + "'";    
              ResultSet rs = stmt.executeQuery(sqlText);
      
              if (rs != null) {
                  while (rs.next()) {
                      if (rs.getString(1).equalsIgnoreCase(tableName)) {
                          System.out.println("Table: " + tableName + " already exists!");
                          exists = true;
                      } else { 
                          System.out.println("Table: " + tableName + " does not appear to exist.");
                          exists = false;
                      }
      
                  }
              }
      
          } catch (SQLException sqlex) {
              sqlex.printStackTrace();
          }
          return exists;
      }
      

      【讨论】:

      • 您可能希望在查询中包含 schema_name 以在不同模式中查找同一个表。
      【解决方案8】:

      最简单的答案是:

      catch{
      
      #create table here
      
      }
      

      如果不存在则创建一个表,如果存在则产生错误。并且错误被捕获。

      【讨论】:

        【解决方案9】:

        http://www.postgresql.org/docs/8.2/static/sql-droptable.html

        DROP TABLE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
        

        【讨论】:

        • 如果该表存在,他不想删除该表。如果它不存在,他想创建它。
        【解决方案10】:

        尝试对表运行查询。如果它抛出异常,则捕获异常并创建一个新表。

        try {
            int a =  db.queryForInt("SELECT COUNT(*) FROM USERS;");
        }
        catch (Exception e) {
            System.out.print(e.toString());
            db.update("CREATE TABLE USERS (" +
                        "id SERIAL," +
                        "PRIMARY KEY(id)," +
                        "name varchar(30) NOT NULL," +
                        "email varchar(30) NOT NULL," +
                        "username varchar(30) NOT NULL," +
                        "password varchar(30) NOT NULL" +
                        ");");
        }
        return db;
        

        【讨论】:

          猜你喜欢
          • 2011-09-03
          • 2011-04-12
          • 2011-05-05
          • 2012-04-11
          • 2021-04-02
          • 1970-01-01
          • 2014-11-11
          • 1970-01-01
          • 2016-06-25
          相关资源
          最近更新 更多