Using BigInteger as argument to AbstractJdbc2Statement.setObject

Поиск
Список
Период
Сортировка
От Sylvain Leroux
Тема Using BigInteger as argument to AbstractJdbc2Statement.setObject
Дата
Msg-id 4A79587F.6010603@wanadoo.fr
обсуждение исходный текст
Ответы Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject
Список pgsql-jdbc
Hi,

I am using Jython to access a PostgreSQL database throught the JDBC driver.

I have a problem with a code fragment like that:
>         stmt = self.conn.prepareStatement("INSERT INTO campagne(id) VALUES(?)")
>         stmt.setObject(1, 123456899999)

Of course, in the real code, the value 123456899999 is not hard wired.
Anyway, Jython ``autobox'' such values into a java.math.BigInteger object.
But AbstractJdbc2Statement.setObject does not handle that kind of
object. Which leads to the error:
>     stmt.setObject(1, 123456899999)
>         at org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:1735)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:597)
>
> org.postgresql.util.PSQLException: org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance
of 
> java.math.BigInteger. Use setObject() with an explicit Types value to specify the type to use.

Since the column campagne(id) is a NUMERIC, as the error message
suggests, I could write something like that instead:
>         stmt.setObject(1, 123456899999, Types.NUMERIC)

But this defeats the purpose of using a scripting language both for
simplicity and dynamic typing.

Moreover other scripting languages for the Java platform may exhibit the
same behavior. So, it would be great if we have support for passing
BigInteger as argument to the setObject method in prepared statements.
Even if it's not required by the JDBC API.

Best of all, the patch is trivial as you will see: I send the result of
a ``cvs diff -u8pN'' as an attachment.


Best regards,
Sylvain Leroux

--
Website: http://www.chicoree.fr
Index: org/postgresql/jdbc2/AbstractJdbc2Statement.java
===================================================================
RCS file: /cvsroot/jdbc/pgjdbc/org/postgresql/jdbc2/AbstractJdbc2Statement.java,v
retrieving revision 1.114
diff -u -8 -p -r1.114 AbstractJdbc2Statement.java
--- org/postgresql/jdbc2/AbstractJdbc2Statement.java    27 May 2009 23:55:19 -0000    1.114
+++ org/postgresql/jdbc2/AbstractJdbc2Statement.java    5 Aug 2009 09:30:00 -0000
@@ -1224,16 +1224,36 @@ public abstract class AbstractJdbc2State
      */
     public void setDouble(int parameterIndex, double x) throws SQLException
     {
         checkClosed();
         bindLiteral(parameterIndex, Double.toString(x), Oid.FLOAT8);
     }

     /*
+     * Set a parameter to a java.lang.BigInteger value.  The driver
+     * converts this to a SQL NUMERIC value when it sends it to the
+     * database.
+     *
+     * <b>This is an extension to the JDBC API!</b>
+     *
+     * @param parameterIndex the first parameter is 1...
+     * @param x the parameter value
+     * @exception SQLException if a database access error occurs
+     */
+    public void setBigInteger(int parameterIndex, BigInteger x) throws SQLException
+    {
+        checkClosed();
+        if (x == null)
+            setNull(parameterIndex, Types.DECIMAL);
+        else
+            bindLiteral(parameterIndex, x.toString(), Oid.NUMERIC);
+    }
+
+    /*
      * Set a parameter to a java.lang.BigDecimal value.  The driver
      * converts this to a SQL NUMERIC value when it sends it to the
      * database.
      *
      * @param parameterIndex the first parameter is 1...
      * @param x the parameter value
      * @exception SQLException if a database access error occurs
      */
@@ -1731,16 +1751,18 @@ public abstract class AbstractJdbc2State
     {
         checkClosed();
         if (x == null)
             setNull(parameterIndex, Types.OTHER);
         else if (x instanceof String)
             setString(parameterIndex, (String)x);
         else if (x instanceof BigDecimal)
             setBigDecimal(parameterIndex, (BigDecimal)x);
+        else if (x instanceof BigInteger)
+            setBigInteger(parameterIndex, (BigInteger)x);
         else if (x instanceof Short)
             setShort(parameterIndex, ((Short)x).shortValue());
         else if (x instanceof Integer)
             setInt(parameterIndex, ((Integer)x).intValue());
         else if (x instanceof Long)
             setLong(parameterIndex, ((Long)x).longValue());
         else if (x instanceof Float)
             setFloat(parameterIndex, ((Float)x).floatValue());

В списке pgsql-jdbc по дате отправления:

Предыдущее
От: Michael Schwipps
Дата:
Сообщение: float4 or real in function parameter -> PSQLException: ERROR function in_test4(double precision) does not exist
Следующее
От: Oliver Jowett
Дата:
Сообщение: Re: Using BigInteger as argument to AbstractJdbc2Statement.setObject