PreparedStatement IF EXISTS throws:org.postgresql.util.PSQLException:列索引超出范围:1,列数:0

时间:2017-11-15 16:36:46

标签: java postgresql prepared-statement postgresql-9.6

以下代码抛出异常:

String sql = "DO $$ " +
            "BEGIN " +
            "IF EXISTS ( SELECT column_name FROM information_schema.COLUMNS WHERE table_name='myTable' AND column_name='myColumn') THEN " +
            "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1; " +
            "END IF; " +
            "END " +
            "$$; ";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql)
pstmt.setString(1, "bla bla"); // <--- EXCEPTION HERE
pstmt.executeUpdate();

如果我将sql更改为this,那就没问题了:

String sql = "UPDATE myTable SET \"myColumn\"=? WHERE \"id\"=1;";

我做错了什么?我想更新一些列只有它们存在...

1 个答案:

答案 0 :(得分:0)

Postgres文档说:

  

PREPARE name [(data_type [,...])] AS语句

     

...

     

语句

Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement.

https://www.postgresql.org/docs/9.6/static/sql-prepare.html

所以看来你无法准备匿名代码块,我想你的代码:

PreparedStatement pstmt = c.prepareStatement(sql)

没有准备任何东西。您可以通过发出sql请求来检查它:

select * from pg_prepared_statements;

如果你改变你的代码:

String sql = "DO $$ whatever $$;";

Connection c = DriverManager.getConnection(...);
PreparedStatement pstmt = c.prepareStatement(sql);
((org.postgresql.PGStatement)pstmt).setPrepareThreshold(1); // <-- Add this line
// pstmt.setString(1, "bla bla"); // comment it out
pstmt.executeUpdate();

你得到关于准备错误陈述的实际postgres错误。