On Aug 31, 2012, at 21:53, Samuel Gendler <sgend...@ideasculptor.com> wrote:

> I have the following crosstab query, which needs to be parameterized in the 2 
> inner queries:
> 
> SELECT * FROM crosstab(
> $$
>     SELECT t.local_key, 
>            s.sensor_pk, 
>            CASE WHEN t.local_day_abbreviation IN (?,?,?,?,?,?,?) THEN 
> q.dpoint_value 
>            ELSE NULL 
>            END as dpoint_value 
>     FROM dimensions.sensor s
>     INNER JOIN dimensions.time_ny t
>         ON s.building_id = ?
>         AND s.sensor_pk IN 
> (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
>         AND t.local_key BETWEEN ? AND ?
>     LEFT OUTER JOIN (
>         SELECT f.time_fk, f.sensor_fk,
>                cast(avg(f.dpoint_value) as numeric(10,2)) as dpoint_value
>         FROM facts.bldg_4_thermal_fact f
>         WHERE f.time_fk BETWEEN ? AND ?
>           AND f.sensor_fk IN 
> (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
>         GROUP BY 1,2) q
>         ON q.time_fk = t.local_key
>         AND q.sensor_fk = s.sensor_pk
>     ORDER BY 1,2
> $$,
> $$
>     SELECT s.sensor_pk
>     FROM dimensions.sensor s
>     WHERE s.building_id = ?
>       AND s.sensor_pk IN 
> (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)
>     ORDER BY 1
> $$
> ) q(time_key bigint, a4052 real,a4053 real,a4054 real,a4055 real,a4056 
> real,a4057 real,a4058 real,a4059 real,a4060 real,a4061 real,a4062 real,a4063 
> real,a4064 real,a4065 real,a4066 real,a4067 real,a4068 real,a4069 real,a4070 
> real,a4071 real,a4072 real,a4073 real,a4074 real,a4075 real,a4076 real,a4077 
> real,a4078 real,a4079 real)
> 
> 
> 
> 
> However, when I attempt to create a prepared statement in java (or groovy, or 
> as a hibernate sqlQuery object) with the following set of parameters (the 
> counts do match), I always get an exception telling me the following
> 
> 
> 
> 
> [Mon, Tue, Wed, Thu, Fri, Sat, Sun, 4, 4052, 4053, 4054, 4055, 4056, 4057, 
> 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 
> 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 201204020000, 
> 201204040000, 201204020000, 201204040000, 4052, 4053, 4054, 4055, 4056, 4057, 
> 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 4068, 4069, 4070, 
> 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079, 4, 4052, 4053, 4054, 
> 4055, 4056, 4057, 4058, 4059, 4060, 4061, 4062, 4063, 4064, 4065, 4066, 4067, 
> 4068, 4069, 4070, 4071, 4072, 4073, 4074, 4075, 4076, 4077, 4078, 4079]
> 
> Caused by: org.postgresql.util.PSQLException: The column index is out of 
> range: 1, number of columns: 0.
>       at 
> org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:53)
>       at 
> org.postgresql.core.v3.SimpleParameterList.setStringParameter(SimpleParameterList.java:118)
>       at 
> org.postgresql.jdbc2.AbstractJdbc2Statement.bindString(AbstractJdbc2Statement.java:2184)
>       at 
> org.postgresql.jdbc2.AbstractJdbc2Statement.setString(AbstractJdbc2Statement.java:1303)
>       at 
> org.postgresql.jdbc2.AbstractJdbc2Statement.setString(AbstractJdbc2Statement.java:1289)
>       at 
> org.postgresql.jdbc2.AbstractJdbc2Statement.setObject(AbstractJdbc2Statement.java:1763)
>       at 
> org.postgresql.jdbc3g.AbstractJdbc3gStatement.setObject(AbstractJdbc3gStatement.java:37)
>       at 
> org.postgresql.jdbc4.AbstractJdbc4Statement.setObject(AbstractJdbc4Statement.java:46)
>       at 
> org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:169)
>       at 
> org.apache.commons.dbcp.DelegatingPreparedStatement.setObject(DelegatingPreparedStatement.java:169)
> 
> 
> 
> 
> I've tried a number of different escaping mechanisms but I can't get anything 
> to work.  I'm starting to think that postgresql won't allow me to use do 
> parameter replacement in the inner queries.  Is this true? The query runs 
> just fine if I manually construct the string, but some of those params are 
> user input so I really don't want to just construct a string if I can avoid 
> it.
> 
> Any suggestions?
> 
> Or can I create a prepared statement and then pass it in as a param to 
> another prepared statement?
> 
> Something like:
> 
> SELECT * FROM crosstab(?, ?) q(time_key bigint, a4052 real,a4053 real,a4054 
> real,a4055 real,a4056 real,a4057 real,a4058 real,a4059 real,a4060 real,a4061 
> real,a4062 real,a4063 real,a4064 real,a4065 real,a4066 real,a4067 real,a4068 
> real,a4069 real,a4070 real,a4071 real,a4072 real,a4073 real,a4074 real,a4075 
> real,a4076 real,a4077 real,a4078 real,a4079 real)
> 
> With each '?' being passed a prepared statement?  That'd be a really cool way 
> to handle it, but it seems unlikely to work.
> 
> Doing the whole thing in a stored proc isn't really easily done - at least 
> with my limited knowledge of creating stored procs, since all of the lists 
> are of varying lengths, as are the number of returned columns (which always 
> matches the length of the last 3 lists plus 1.
> 
> 

Question marks inside a string have no special meaning.

Select * from crosstab(?,?) would work fine but the values you pass are still 
just literal strings

All those "?" are a pain syntax wise.  Consider the following (concept, syntax 
may need tweaking)

Select * from numbers where num = ANY ( split_to_array($$'1,3,5,7,11'$$, 
',')::int[] )

In this case you pass a single delimited string (replacing the $-quoted literal 
shown) with whatever values you want as a single parameter/input.  Convert that 
string to an array and then use the =ANY array operator to match the column 
against the array.  You could also just pass an array but I haven't tried that 
in Java but I do know how to pass strings and let PostgreSQL convert them.

Not much more help as I have not used the crosstab function...but it seems you 
probably will need to build the sub-queries as literals.  Lookup the various 
quote_ functions the help protect yourself if you do this.

David J.











-- 
Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-sql

Reply via email to