【问题标题】:Run PL/pgSQL script using java使用 java 运行 PL/pgSQL 脚本
【发布时间】:2016-10-17 13:54:17
【问题描述】:

可以使用 java 运行 PL/pgSQL 脚本吗?我正在从 java 代码创建 postgres db,需要在这个 db 上创建一些函数。

我知道我可以像这样使用 DriverManager 运行任何 sql 脚本:

Connection connection = DriverManager.getConnection(
              connectionToDbUrl,
              getDbUser(),
              getDbPassword());
Statement statement = connection.createStatement()
statement.execute("select * from table);

但它不会执行 PL/pgSQL 脚本。有什么想法吗?

编辑:我的意思是 PL/pgSQL

编辑 2:感谢@a_horse_with_no_name 解决方案,我发现了错误。 我使用 BufferedReader 从文件中读取脚本并加入所有行。在每行末尾添加“\n”可以解决问题。

try (BufferedReader br = new BufferedReader(new FileReader(resource.getFile())))
    {
    statement.execute(br.lines().collect(Collectors.joining(" \n")));
    }

【问题讨论】:

  • 您的意思是PL/pgSQL 吗?
  • PSQL 基本上是 Postgres 的 shell 或终端,具有许多专有语法。我假设你基本上可以从你的 java 程序中拉出一个命令 shell,但你最好编写实际的 SQL 并通过 JDBC 运行它。
  • @Aaron 是的,我的意思是 PL/pgSQL
  • @a_horse_with_no_name 我想在新数据库上创建函数,而不是运行一个
  • @a_horse_with_no_name 到底有多准确?当脚本在 PL/pgSQL 中时,由 statement.execute 运行会引发异常

标签: java postgresql jdbc plpgsql


【解决方案1】:

这对我有用:

Connection con = DriverManager.getConnection("jdbc:postgresql://localhost/postgres", "...", "******");

Statement stmt = con.createStatement();

String create =
  "create function the_answer() \n" +
  "returns integer as $$\n" +
  "begin \n" +
  "   return 42;\n" +
  "end;\n" +
  "$$\n" +
  "language plpgsql;";

// create the function
stmt.execute(create);

// use the function
ResultSet rs = stmt.executeQuery("select the_answer()");
rs.next();
System.out.println("The answer is: " + rs.getInt(1));

【讨论】:

    【解决方案2】:

    您应该参考 PostgreSQL JDBC 文档: https://www.postgresql.org/docs/7.4/static/jdbc-callproc.html

    如果你的 pgSQL 返回一个值,就这样调用它:

    ResultSet rs = stmt.executeQuery("SELECT * FROM your_func()");
    

    【讨论】:

      【解决方案3】:

      PL/pgSQL 是调用存储过程(或函数或包)的一种特殊情况。

      你必须使用CallableStatement添加de对应的参数。请参阅this 示例。

      【讨论】:

        【解决方案4】:

        我遇到了同样的问题,但我必须以稍微不同的方式解决它,我希望在这里与其他人分享。

        我发现使用 JDBC 方法相当笨拙。我想使用一种尽可能接近从终端使用 pgqsl 的方法。

        要求 1:作为使用此方法的先决条件,您应该已经能够在终端上运行 pgsql 命令。

        要求 2:用户主目录中的 .pgpass 文件或 PGPASSFILE 引用的文件可以包含要在连接需要密码时使用的密码(否则未指定密码)。此文件应包含以下格式的行:

        hostname:port:database:username:password

        所以在你的主目录中创建一个文件 .pgpass(或者你可能觉得实际需要的任何其他地方,因为你以后需要引用这个位置)

        要求 3:.pgpass 需要限制访问,否则您将收到此错误 - .pgpass" has group or world access; permissions should be u=rw (0600) or less。要解决这个问题,只需将文件 chmod 到至少 600 chmod 600 ~/.pgpass

        要求4:添加这段java代码来执行你的sql脚本。将 替换为您在 .pgpass 文件中使用的值

        System.setProperty("PGPASSFILE", "~/.pgpass");
        Process process = Runtime.getRuntime().exec("psql -U <username> -h <hostname> -d <database> -f src/main/resources/schema.sql");
                try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
                    String line;
                    while ((line = reader.readLine()) != null) {
                        System.out.println(line);
                    }
                }
                int ret = process.waitFor();
                System.out.printf("Program exited with code: %d%n", ret);
        

        那应该为你做!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-27
          • 1970-01-01
          • 2014-02-04
          • 1970-01-01
          • 2013-10-19
          • 1970-01-01
          相关资源
          最近更新 更多