Cannot use parametrization on "set variable = ?" statement but hardcoding works - postgresql

I want to change the parameter statement_timeout after establishing a JDBC connection. Therefore I have the following code:
PreparedStatement statement = _connection.prepareStatement("set statement_timeout = ?");
statement.setInt(1, (int) _statementTimeout);
statement.execute();
But on execute() this results in a SQL exception clearly stating that I have an error in the syntax at my question mark.
org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1"
Position: 25
I tried searching for this problem but couldn't find any right answers. The pages thinks I refer to the SET of an UPDATE-clause.
My question is simple, why is parametrization not working? If I hardcode the value, e.g.
prepareStatement(String.format("set statement_timeout = %s", _statementTimeout))
everything works fine and as expected. Or is it simply wrong to use parametrization on setting variables?

Using the equivalent function call should work:
prepareStatement("select set_config('statement_timeout', ?, false)");
statement.setString(1, Integer.toString(_statementTimeout));
statement.execute();
Note that you need to pass the value as a String as the function's signature is (text, text, boolean)

Related

Why single quote escape cannot be used in QuestDB, Error: dangling expression

I'm trying to use Query Variables in Grafana, the panel query source is PostgreSQL for QuestDB.
I have added the variable without any issue, but I'm unable to use the variable in Panel query since the variable values contains the spaces (SENSOR01 ON_OFF), also I'm unable to figure-out how to add single quote escape.
Following are the scenarios I tried:
Scenario1: this indicates due to space in the Variable value, on_off considered as separate word
where sensor_name = $sensor
db query error: pq: unexpected token: on_off
.
.
Scenario2: tried to add single quotes explicitly for the variable value, but there is generic error from source DB (QuestDB)
where sensor_name = concat('''', $sensor, '''')
db query error: pq: dangling expression
When tried Scenario2 approach directly in query of Variable, getting the same error
..
Scenario3: Hard-coded the variable value with space and with single quotes, but this giving me error with first part of the variable, looks like the hard-coded single quotes not passed here!
Error (Scenario3):
Is there any way/workaround to tackle this issue?
Could you just add the quotes directly in the query?
where sensor_name = '$sensor'
I have a similar grafana panel querying a questDB database using a variable and it works for me. This is my query:
select device_type, avg(duration_ms) as avg_duration_ms, avg(speed) as avg_speed, avg(measure1) as avg_m1, avg(measure2) as avg_m2 from ilp_test
WHERE
$__timeFilter(timestamp) and device_type = '$deviceType'
A rather hacky workaround would be to do:
where sensor_name = concat(cast(cast('&' as int) + 1 as char), $sensor, cast(cast('&' as int) + 1 as char))
This should work, but I'm pretty sure there is a better solution. Let me find it and get back to you.
Update. We may support Postgres syntax (which is '' escaping for a single quote char) in one of upcoming versions. For now, you'd have to use the above workaround.

Why do I get a "unterminated quoted string at or near" error using python postgresql, and not in pgadmin, whith the same request?

I have this query :
INSERT INTO lytnobjects.devices (id,idedge,uniqueref,constructeur,ipaddress,macaddress,
hostname,devicetype,isfirewall,isvisible,iscorporate,
ishub,osname,osversion,datecreation,lasttrafic,
hourtrafic,daytrafic,monthtrafic)
VALUES ('e1e455e98b6ed0037a58d0c1f5dc245a',3183,'TODO','TODO','192.168.143.49',
'b0:0c:d1:bb:36:1c','HPBB361C','Other',False,False,False,False,'','',
'2021-10-29T00:58:53.709','2021-01-01T00:00:00','0/0','0/0','0/0')
When I execute the query using python 3.9 and psycopg2_binary (PostgreSQL), I get an error :
unterminated quoted string at or near "'HPBB361C"
conn is the opened connection to the database (AWS RDS PostgreSQL)
sql is a string with the query above
def SQLExec(conn,sql):
try: cur = conn.cursor()
cur.execute(sql)
except (Exception, psycopg2.DatabaseError) as error:
print("***** ERROR:",error)
cur.close()
If I execute the same request from pgAdmin, I get no error !
There is no missing quote as you can see in the query, and no reason to point an error at this place!
So, I have a string (sql) with the query ("INSERT ...")
I call execute from psycopg2, and get an error: unterminated quoted string at or near "'HPBB361C"
I copy/paste the same string into pgAdmin, and the query is executed with no error
The same string (query)
Any idea why I get an error from my python app?
I am looking for an answer since many hours, but find no explanation, and I don't know how to fix the problem (which doesn't exist for me)
Your help is very appreciated
Thank you
I finaly found the answer!
I build the sql query (string) using some variables coming from various sources, like Amazon S3 for instance.
I assumed that the variable was really a string, with nothing "bizarre" in it... But in fact, sometimes, the "string" was ended with a "\x00" char, that is not displayed, so the string looks just normal :-/
When I execute my query (string) with psycopg2, it receives the extra \x00 char, which ends the string at this place! This is why it says there is a missing quote
I put a trace in the code to display the .encode() version of my string, and it revealed the \x00 at the end. So now I "clean" all string variables used in my queries, just with myvariable.replace("\x00","")
And it works now. There is probably a more conventional way to fix this...
I hope it may help somebody sometime! ;-)

Postgres, query error: ERROR: operator does not exist: character varying = bigint?

I am trying to run this query:
select *
from my_table
where column_one=${myValue}
I get the following error in Datagrip:
[42883] ERROR: operator does not exist: character varying = bigint Hint: No operator matches the given name and argument types. You might need to add explicit type casts.
Now, I have found this question, and I can fix the error by putting a string like this:
select *
from my_table
where column_one='123'
What I need is a way to pass in the '123' as a parameter. I usually do this ${myValue} and it works, but I am not sure how to keep my variable there as an input so I can run dynamic queries in code and let Postgres understand I want to pass in a string and not a number.
Any suggestions?
Here's a screenshot of how I am putting the parameter value in DataGrip...:
Ok, so, I just tried to put quotes in the data grip parameters input field for myValue #thirumal's answer things work. I didn't know I have to quote the value for it to work.
This is what it looks like:
Type cast ${myValue} using SQL Standard,
cast(${myValue} AS varchar)
or using Postgres Syntax:
${myValue}::varchar

How to insert similar value into multiple locations of a psycopg2 query statement using dict? [duplicate]

I have a Python script that runs a pgSQL file through SQLAlchemy's connection.execute function. Here's the block of code in Python:
results = pg_conn.execute(sql_cmd, beg_date = datetime.date(2015,4,1), end_date = datetime.date(2015,4,30))
And here's one of the areas where the variable gets inputted in my SQL:
WHERE
( dv.date >= %(beg_date)s AND
dv.date <= %(end_date)s)
When I run this, I get a cryptic python error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) argument formats can't be mixed
…followed by a huge dump of the offending SQL query. I've run this exact code with the same variable convention before. Why isn't it working this time?
I encountered a similar issue as Nikhil. I have a query with LIKE clauses which worked until I modified it to include a bind variable, at which point I received the following error:
DatabaseError: Execution failed on sql '...': argument formats can't be mixed
The solution is not to give up on the LIKE clause. That would be pretty crazy if psycopg2 simply didn't permit LIKE clauses. Rather, we can escape the literal % with %%. For example, the following query:
SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%';
would need to be modified to:
SELECT *
FROM people
WHERE start_date > %(beg_date)s
AND name LIKE 'John%%';
More details in the pscopg2 docs: http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries
As it turned out, I had used a SQL LIKE operator in the new SQL query, and the % operand was messing with Python's escaping capability. For instance:
dv.device LIKE 'iPhone%' or
dv.device LIKE '%Phone'
Another answer offered a way to un-escape and re-escape, which I felt would add unnecessary complexity to otherwise simple code. Instead, I used pgSQL's ability to handle regex to modify the SQL query itself. This changed the above portion of the query to:
dv.device ~ E'iPhone.*' or
dv.device ~ E'.*Phone$'
So for others: you may need to change your LIKE operators to regex '~' to get it to work. Just remember that it'll be WAY slower for large queries. (More info here.)
For me it's turn out I have % in sql comment
/* Any future change in the testing size will not require
a change here... even if we do a 100% test
*/
This works fine:
/* Any future change in the testing size will not require
a change here... even if we do a 100pct test
*/

Why am I getting a syntax error when calling my stored procedure?

I am trying to call a stored procedure with Time variable as in parameter. But whenever i try to call the procedure i m getting error as:
db2 'call PASS_FAIL_CHECKDATE('2014-01-21','13:42:25','CSS1',Null,'4500096651','10',Null)'
SQL0104N An unexpected token ":42" was found following "CKDATE(2014-01-21,
13". Expected tokens may include: "+". SQLSTATE=42601
My Procedures input parameter are :
PASS_fail_checkdate (in post_date date,in post_time time,in destplant varchar(4), in destloc varchar(4), in transnum varchar(10), in translineitemnum varchar(6), in inboundconsignment varchar(35))
I am not sure if my declaration for time variable is correct in procedure or if i am calling the time variable correctly in the procedure.
Please give me suggestions on the same.
As already offered, in words, try the following example as a revision to what was noted in the OP as tried already but failing; i.e. change to use double-quote vs the apostrophe, specified as the delimiter for the DB2 SQL statement string:
db2 "call PASS_FAIL_CHECKDATE('2014-01-21','13:42:25','CSS1',Null,'4500096651','10',Null)"