Sunday, September 21, 2008

Re: [JDBC] PreparedStatement.toString() creates valid SQL; was: Q: use setObject also for int or string

import java.sql.*;
import java.io.ByteArrayInputStream;

public class PrintQuery {

public static void main(String args[]) throws Exception {

Class.forName("org.postgresql.Driver");

Connection conn = DriverManager.getConnection("jdbc:postgresql://localhost:5432/jurka", "jurka", "");
PreparedStatement ps = conn.prepareStatement("SELECT ?");

ps.setString(1, "NULL");
System.out.println(ps.toString());

ps.setString(1, "a\\b");
System.out.println(ps.toString());

byte data[] = new String("data").getBytes("US-ASCII");
ByteArrayInputStream bais = new ByteArrayInputStream(data);
ps.setBinaryStream(1, bais, data.length);
System.out.println(ps.toString());
System.out.println(ps.toString());

conn.close();
}
}

On Sun, 21 Sep 2008, Michael Enke wrote:

> I did this and it would be great if you could have a look into the
> attached patch files and make comments.
>
> It has to set standard_conforming_strings to false
> in any case to create valid sql:
> If I use setString(1, "a\\b");
> the real stored characters are 'a','\','b'.
> If I would use standard_conforming_strings=true
> the output would be "a\b"
> but with set to false the output is "a\\b" which is the correct one.

One of the backslashes is used for Java's escaping, so the real data does
only have one backslash which is the correct behavior for
standard_conforming_strings. Also note that E'' syntax is only supported
on 8.1 and later servers, so it can't be used unconditionally.

> I did not understand what you mean with InputStream.

See the attached test case.

Also note that the String "NULL" should be 'NULL', not plain NULL.

Kris Jurka

No comments: