PostgreSQL JDBC - 使用 PreparedStatements 创建表时已存在关系

Posted

技术标签:

【中文标题】PostgreSQL JDBC - 使用 PreparedStatements 创建表时已存在关系【英文标题】:PostgreSQL JDBC - relation already exists when creating table using PreparedStatements 【发布时间】:2017-11-29 18:09:36 【问题描述】:

所以我正在使用连接创建一个 JDBC 程序。这是我第一次熟悉这种编程,所以如果我的问题是“愚蠢的”,请原谅。但是我已经在这个问题上停留了一段时间。我创建了 4 个新表。它编译得很好,但是当我运行它时,我得到一个“错误:关系“笑话”已经存在”。当我删除 createTableJoke 准备好的语句时,我的礼品表出现相同的错误(“错误:关系“礼物”已经存在”)。我的所有陈述都是如此。我做错了什么,PostgreSQL为什么这样做背后的逻辑是什么?我在下面包含了我的代码:

private static void createTables() throws SQLException 

PreparedStatement createTableJoke = null;
PreparedStatement createTableGift = null; 
PreparedStatement createTableHat = null;
PreparedStatement createTableCracker = null;
Connection conn = null; 
try 
    conn = getDBConnection();
    createTableJoke = conn.prepareStatement("CREATE TABLE Joke ( jid INTEGER PRIMARY KEY, joke CHAR(200) NOT NULL, royalty FLOAT NOT NULL);");
    createTableJoke.executeUpdate();
    createTableGift = conn.prepareStatement("CREATE TABLE Gift ( gid INTEGER PRIMARY KEY, description CHAR(100) NOT NULL, price FLOAT NOT NULL);");
    createTableGift.executeUpdate();
    createTableHat = conn.prepareStatement("CREATE TABLE Hat ( hid INTEGER PRIMARY KEY, description CHAR(100) NOT NULL, price FLOAT NOT NULL);");
    createTableHat.executeUpdate();
    createTableCracker = conn.prepareStatement("CREATE TABLE Cracker (cid INTEGER PRIMARY KEY, name CHAR(20) NOT NULL, jid INTEGER REFERENCES Joke(jid), gid INTEGER REFERENCES Gift(gid), hid INTEGER REFERENCES Hat(hid), saleprice NUMERIC CHECK (saleprice > 0), quantity INTEGER NOT NULL);");
    createTableCracker.executeUpdate();
 catch (SQLException e)
    System.out.println(e.getMessage());

finally 
    if ((createTableJoke != null) && (createTableGift != null) && (createTableHat != null) && (createTableCracker != null))
        createTableJoke.close();
        createTableGift.close();
        createTableHat.close();
        createTableCracker.close();
     
    if (conn != null) 
        conn.close();
    

【问题讨论】:

“已经存在”的哪一部分让您感到困惑?您显然已经运行了一次程序而没有错误,所以现在这些表存在于数据库中。如果数据库不保留您创建的内容,它还有什么意义? 好奇:你为什么用PreparedStatement来执行DDL语句?请改用 Statement,并将其重用于所有 4 个 executeUpdate 调用。 【参考方案1】:

有两种情况:

    您不必关心是否保留现有表(如果有的话)。在这种情况下,在创建它之前发出“DROP TABLE IF EXISTS Joke”。这将确保表被删除,当表不存在时它不会失败。

    您关心表的现有内容。在这种情况下,发出“CREATE TABLE IF NOT EXISTS Joke”...而不是普通的 CREATE TABLE。这将确保表在那里,如果它已经存在,则不会创建它。另请注意,如果您在 create 语句中更改了结构并且表存在,则结构中的更改将不适用。

【讨论】:

【参考方案2】:

这种错误意味着,所有这个表都已经创建了。使用pgAdmin(在Microsoft Windows 操作系统上通常与PostgreSQL 一起安装)或psql 客户端连接到数据库并检查表是否存在。

【讨论】:

以上是关于PostgreSQL JDBC - 使用 PreparedStatements 创建表时已存在关系的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 连接到 PostgreSql 的本地实例

如何使用 JDBC 调用 PostgreSQL 存储过程

如何做批处理 jdbc/insert!和 jdbc/更新!在 Clojure 中使用 postgresql?

使用 JDBC 准备语句插入时出错

使用 JDBC 连接到 PostgreSQL 数据库时选择角色

无论是不是使用 UTF8 编码,Postgresql/JDBC 都会失败