我试试
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.Reader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import com.ibatis.common.jdbc.ScriptRunner;
public static void createDatabase() throws ClassNotFoundException, SQLException {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection("jdbc:postgresql://127.0.0.1:5432/postgres", "postgres", "123456a@");
Statement stmt = connection.createStatement();
stmt.executeQuery("CREATE DATABASE IF NOT EXISTS foo");
stmt.executeQuery("USE foo");
connection.close();
}
和
public static void dropDatabase() throws ClassNotFoundException, SQLException {
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection("jdbc:postgresql://127.0.0.1:5432/", "postgres", "123456a@");
Statement statement = connection.createStatement();
statement.executeUpdate("DROP DATABASE foo");
connection.close();
}
但创建,也丢弃方法不成功。
调用create method时出错:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: syntax error at or near "NOT"
Position: 20
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2453)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2153)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:286)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:432)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:358)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:305)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:291)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:269)
at org.postgresql.jdbc.PgStatement.executeQuery(PgStatement.java:236)
at com.nttdata.RunSqlScript.createDatabase(RunSqlScript.java:57)
at com.nttdata.RunSqlScript.main(RunSqlScript.java:27)
调用drop方法时出错:
Exception in thread "main" org.postgresql.util.PSQLException: ERROR: database "foo" is being accessed by other users
Detail: There is 1 other session using the database.
at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2453)
at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2153)
at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:286)
at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:432)
at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:358)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:305)
at org.postgresql.jdbc.PgStatement.executeCachedSql(PgStatement.java:291)
at org.postgresql.jdbc.PgStatement.executeWithFlags(PgStatement.java:269)
at org.postgresql.jdbc.PgStatement.executeUpdate(PgStatement.java:249)
at com.nttdata.RunSqlScript.dropDatabase(RunSqlScript.java:71)
at com.nttdata.RunSqlScript.main(RunSqlScript.java:28)
答案 0 :(得分:3)
首先,在您的问题中创建数据库时使用的SQL语法不正确。堆栈跟踪说明了不正确的语法。
如果要检查数据库是否存在,那么您可能需要在Java代码中执行以下操作:
ResultSet rs = stmt.executeQuery("select datname from pg_database where datname like 'foo';");
不是IF NOT EXISTS
方法
访问此rs
对象将告诉您数据库是否存在。然后,您可以相应地触发CREATE
或DELETE
数据库操作。
String databaseName = "";
if(rs.next()) {
databaseName = rs.getString("datname");
}
stmt.executeQuery("DROP DATABASE " + databaseName);
如果直接DROP DATABASE
不起作用(我曾经多次面对过),您可以考虑使用dropdb
实用程序或以下方法之一。
<强> APPROACH-1 强>
使用以下查询来防止将来与您的数据库建立连接:
REVOKE CONNECT ON DATABASE foo FROM public;
然后,您可以终止除此之外的所有与此数据库的连接:
SELECT pid, pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE datname = current_database() AND pid <> pg_backend_pid();
由于您已将CONNECT权限撤销到相应的数据库,因此不再有外部auto-connect
将无法执行此操作。您现在可以毫无问题地删除数据库。
<强> APPROACH-2:强>
这种方法采用批处理作业方式,您可以从相应的jar中调用此类:
Process batchProcess = Runtime.getRuntime().exec("C:/Program Files/PostgreSQL/9.5/bin/psql -h \"DB SERVER ADDRESS\" -U postgres -f C:/batch.sql");
batch.sql
包含SQL DROP DATABASE语句,在执行时将被删除。
希望这有帮助!
答案 1 :(得分:1)
您可以尝试使用的选项是使用liquibase之类的数据库迁移工具。您可以从liquibase尝试几种选择。一种是从代码直接执行可执行文件(首先使用更改集创建数据库更改日志文件。更改集中的一个命令将是可执行文件
<changeSet author="exec-change-drop" id="drop-foo">
<executeCommand executable="<bat file with drop for PSQL or dropdb>"/>
</changeSet>
您可以尝试的另一个选项是编写一个sql并调用它
<changeSet id="exec-change-drop2" author="drop-foo-2">
<sql>DROP DATABASE foo;</sql>
</changeSet>
然后,您可以按照以下代码执行此操作
Class.forName("org.postgresql.Driver");
Connection connection = DriverManager.getConnection("jdbc:postgresql://127.0.0.1:5432/postgres", "postgres", "123456a@");
Database database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(new JdbcConnection(connection));
Liquibase liquibase = new liquibase.Liquibase("path/to/changelog.xml", new ClassLoaderResourceAccessor(), database);
liquibase.update(new Contexts(), new LabelExpression());
请注意,您的changeLogSchema可能需要位于不同的架构中,以便无缝执行。
另外liquibase可以添加maven(这是应该的方式)并执行