PostgreSQL and SSRS: Passing parameters to PostgreSQL function - postgresql

I tried to use postgreSQL stored function in ssrs, firstly tried using like this :
select *
from reports.get_daily_cash_flow_test('01.01.2017'::timestamp with time zone,
'01.01.2019'::timestamp with time zone, True, Offset)
WHERE Offset = #Offset
It causes syntax error, near #Offset. #Offset is integer type variable, added in Parameters, and also added in dataset parameters (also tried using query like :
select *
from reports.get_daily_cash_flow_test('01.01.2017'::timestamp with time zone,
'01.01.2019'::timestamp with time zone, True, #Offset)
Just because #Offset is already added in dataset parameters but still syntax error.
After that I tried using function as stored procedure. Still the problem is that my function returns Table, and in dataset parameters it requires me to add output parameters (returned table columns) values.
After that tried using simple query without stored function which looks like that:
SELECT COUNT(DISTINCT (l.player_id))
FROM public.logins l
WHERE (l.login_date between #DateFrom AND #DateTo)
Error message is
An error occurred while executing the query.
ERROR [42703] ERROR: column "datefrom" does not exist;
Error while executing the query

And I found the solution, once executing query you should use it like :
SELECT * FROM reports.get_devices(?,?,?)
question marks instead of parameters, that does the trick.

Related

Equate timestamp with day name in a query and get result set w.r.t day name in PostgreSQL query

I want to equate timestamp with day name in PostgreSQL and I want result set with respect to day name. I tried to use sub query and some functions too but getting syntax errors and function not exist SQL errors. Please help.
I tried to use to_char and to_timestamp functions but I am getting stuck to syntax errors when I am binding them into sub query.First I wrote this query which extracts day from timestamp.
select to_char(TO_TIMESTAMP(1534994169000 / 1000), 'Day');
Then I tried to use this query in sub query shown in code.
select * from tests where testtimestamp = (to_timestamp(TO_TIMESTAMP(1531803015000 / 1000), 'Day'));
select * from tests where testtimestamp = (select to_timestamp(to_char(TO_TIMESTAMP(1534994169000 / 1000), 'Day')))
Errors that I am getting is
SQL Error [42883]: ERROR: function to_timestamp(timestamp with time
zone, unknown) does not exist Hint: No function matches the given
name and argument types. You might need to add explicit type casts.
Position: 44 ERROR: function to_timestamp(timestamp with time zone,
unknown) does not exist Hint: No function matches the given name and
argument types. You might need to add explicit type casts. Position:
44 ERROR: function to_timestamp(timestamp with time zone, unknown)
does not exist Hint: No function matches the given name and argument
types. You might need to add explicit type casts. Position: 44
Since your formatting produces a text output (ie. Wednesday) you need to also do a conversion on the timestamp field in your table to make an equality comparison. I suppose something like this.
select
*
from
tests
where
to_char(TO_TIMESTAMP(testtimestamp / 1000), 'Day')
=
to_char(TO_TIMESTAMP(1534994169000 / 1000), 'Day');
Make sure you use to_char and to_timestamp (in your first query above you did to_timestamp twice, which is what caused the error). If you do happen to work this out, you may want to look into functional indexes to speed this up.
You may use EXTRACT
WHERE extract( day from testtimestamp)
= extract ( day from TO_TIMESTAMP(1534994169000 / 1000) )

Postgresql 9.6, Calling a remote function with data wrapper throws various errors

I've created a function in a database that inserts records into a table. This function returns VOID and takes a VARIADIC text array as an input param. When I run the function from the database locally, it works fine, as expected.
But when I try to run from a different database, using a foreign data wrapper it will not work, throws different errors depending on the method I use.
Here's how I make one kind of call:
SELECT dblink('pg_log',
'SELECT public.insert_log(''usage'', ''txn'', ''dimensions'', ''test'', null,
''pgwrapper'', ''temp_var'', null, null, null, ''Start'', null,
null, null, null);');
That one throws this error:
function returning record called in context that cannot accept type record
When I replace Select dblink with PERFORM dblink, I get this error:
syntax error at or near "PERFORM"
And when I try, SELECT dblink_exec:
I get this error:
statement returning results not allowed
Again, the function works as I have called it locally to test it and it does what it should.
I checked the connection with this and it return OK:
SELECT dblink_connect('pg_log');
Anyone have any ideas why this is failing and suggestions on fixing?
Thanks!
It looks like you need to try SELECT * FROM dblink(...) AS t1(column_name type) instead of SELECT dblink(...).
From the PostgresSQL Documenation:
The function returns the row(s) produced by the query. Since dblink can be used with any query, it is declared to return record, rather than specifying any particular set of columns. This means that you must specify the expected set of columns in the calling query — otherwise PostgreSQL would not know what to expect. Here is an example:
SELECT *
FROM dblink('dbname=mydb options=-csearch_path=',
'select proname, prosrc from pg_proc')
AS t1(proname name, prosrc text)
WHERE proname LIKE 'bytea%';

Out-of-range value when trying to filter on converted datetime value

I'm trying to pull data for certain dates out of a staging table where the offshore developers imported everything in the file, so I need to filter out the "non-data" rows and convert the remaining strings to datetime.
Which should be simple enough but... I keep getting this error:
The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
I've taken the query and pulled it apart, made sure there are no invalid strings left and even tried a few different configurations of the query. Here's what I've got now:
SELECT *
FROM
(
select cdt = CAST(cmplt_date as DateTime), *
from stage_hist
WHERE cmplt_date NOT LIKE '(%'
AND ltrim(rtrim(cmplt_date)) NOT LIKE ''
AND cmplt_date NOT LIKE '--%'
) f
WHERE f.cdt BETWEEN '2017-09-01' AND '2017-10-01'
To make sure the conversion is working at least, I can run the inner query and the cast actually works for all rows. I get a valid data set for the rows and no errors, so the actual cast is working.
The BETWEEN statement must be throwing the error then, right? But I've casted both strings I use for that successfully, and even taken a value out of the table and did a test query using it which also works succesfully:
select 1
WHERE CAST(' 2017-09-26' as DateTime) BETWEEN '2017-09-01' AND '2017-10-01'
So if all the casts work individually, how come I'm getting an out-of-range error when running the real query?
I am guessing that this is due to the fact that in your cmplt_date field there are values which are not valid dates. Yes, I know you are filtering them using a WHERE clause, but know that Logical Processing Order of the SELECT statement is not always the actual order. What does this mean is that sometimes, the SQL Engine my start performing your CAST operation before finishing the filtering.
You are using SQL Server 2012, so you can just add TRY_CAST:
SELECT *
FROM
(
select cdt = TRY_CAST(cmplt_date as DateTime), *
from stage_hist
WHERE cmplt_date NOT LIKE '(%'
AND ltrim(rtrim(cmplt_date)) NOT LIKE ''
AND cmplt_date NOT LIKE '--%'
) f
WHERE f.cdt BETWEEN '2017-09-01' AND '2017-10-01'

PostgreSQL function round and JPA/Hibernate

I have a query which is executed from java application like this:
Query query = getEntityManager().createQuery(hql);
The query looks like this:
String hql = "select * from table a where round(column1, 3) = round(parameter, 3)";
Here column1 is of type Double. The value it holds is like 143.02856666. I need to retain the value as it is, but for some business logic just need to round and compare.
The initial database configured was H2 and this worked fine. Now the database has been changed to Postgres and this query now errors out.
ERROR: function round(double precision, integer) does not exist Hint: No function matches the given name and argument types. You might
need to add explicit type casts.
The round() function in Postgres takes a numeric datatype and needs a cast.
The below query works fine if executed directly in Postgres console.
select * from table a where round(cast(column1 as numeric), 3) = round(cast(parameter as numeric), 3);
The same from java application errors out.
java.lang.IllegalArgumentException: org.hibernate.QueryException: Could not resolve requested type for CAST : numeric
Also tried Query query = getEntityManager().createNativeQuery(hql);
This results in a new error.
org.hibernate.engine.jdbc.spi.SqlExceptionHelper - ERROR: syntax error at or near "where"
If I debug, this errors out when the below line is executed.
List resultList = query.getResultList();
How do I rewrite the query so that it works against Postgres ?
What you are doing with Query query = getEntityManager().createQuery(hql); is calling a jpql-query, which does not support all db-functions like round(v numeric, s integer).
Two Suggestions:
Use BETWEEN and maintain jpql-mapping
Write a NativeQuery -> Query query = em.createNativeQuery(queryString);
Your queryString just has to be altered by your parameters.

Yesod persistent-postgresql rawSql queries with column-list wildcards producing syntax errors

I'm using the persistent-postgresql library from Yesod, and I'd like to execute the following raw query:
SELECT * FROM utterance WHERE is_target IS NULL ORDER BY RANDOM() LIMIT 1000
to select 1000 random utterances with a NULL is_target. However, persistent generates the following SQL when I run my code through rawSql:
SELECT * FROM utterance WHERE is_target IS NULL ORDER BY RANDOM() LIMIT 1000"utterance"."id", "utterance"."message", "utterance"."is_target"
This generates an error in postgresql of syntax error at or near ""utterance"" at character 77.
What am I doing wrong?
I fixed this by using the following query instead:
SELECT ?? FROM utterance WHERE is_target IS NULL ORDER BY RANDOM() LIMIT 1000
rawSql doesn't work with column wildcards, because it enforces strong typing on returned data, so it's trying (and failing) to figure out where to put the column names. You need to explicitly list column names OR use some number of "??" placeholders in the statement and bind them at runtime like,
$ (Entity myType utterance, .... ) -> do ....
If you don't want strong typing, you probably also don't want to use Persistent; that's the entire reason it exists.