简体   繁体   中英

Run PL/pgSQL script using java

It is possible to run PL/pgSQL script using java? I'm creating postgres db from java code and need creating some functions on this db.

I know I can run any sql script using DriverManager like that:

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

but it will not execute PL/pgSQL script. Any ideas?

EDIT: I mean PL/pgSQL

EDIT 2: I found bug thanks @a_horse_with_no_name solution. I read script from file using BufferedReader and join all lines. Adding " \\n" on end of each line solves problem.

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

This works for me:

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));

You should refer to PostgreSQL JDBC documentation for that: https://www.postgresql.org/docs/7.4/static/jdbc-callproc.html

In case your pgSQL returns a value call it like that:

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

PL/pgSQL is a special case of calling a stored procedure (or function or package).

You must use CallableStatement adding de corresponding parameters. See this example.

I ran into this same issue, but I got to solve it in a slightly different way which I wish to share here for anyone else.

I found using the JDBC approach rather clumsy. I wanted to use an approach as close to using pgqsl from the terminal as possible.

Requirement 1 : As a prerequisite to using this approach, you should be able to run pgsql command for the terminal already.

Requirement 2 : The file .pgpass in a user's home directory or the file referenced by PGPASSFILE can contain passwords to be used if the connection requires a password (and no password has been specified otherwise). This file should contain lines of the following format:

hostname:port:database:username:password

So create a file .pgpass in your home directory (or wherever else you may feel like actually since you'll need to reference this location later anyway)

Requirement 3 : .pgpass requires restricted access, otherwise you will get this error - .pgpass" has group or world access; permissions should be u=rw (0600) or less . To fix this, just chmod the file to at least 600 chmod 600 ~/.pgpass

Requirement 4 : Add this piece of java code to execute your sql script. Substitute <username>, <hostname> and <database> with the values you used in the .pgpass file

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);

And that should do it for you!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM