Can I set session variables for Postgres from the JDBC Connection - postgresql

For performance reasons, I'm trying to limit the round trips I make to the database. Currently I connect and the issue a series of statements like SET TIMEZONE='America/New_York' to postgres. Many databases allow session variables and similar settings to be passed to the database either as part of the jdbc url i.e. jdbc:postgresql://localhost:5435/test?timezone=America/New_York or by adding the it to the property list like this...
String url = "jdbc:postgresql://localhost/test:5435";
Properties props = new Properties();
props.setProperty("user","fred");
props.setProperty("password","secret");
props.setProperty("timezone","America/New_York");
Connection conn = DriverManager.getConnection(url, props);
I can't find definitive information if this is supported by postgres and tests have failed.

The documentation says:
Connection Parameters
[...]
options = String
Specify 'options' connection initialization parameter.
The value of this property may contain spaces or other special characters, and it should be properly encoded if provided in the connection URL. Spaces are considered to separate command-line arguments, unless escaped with a backslash (\); \\ represents a literal backslash.
So you should use
props.setProperty("options", "-c timezone=America/New_York");

Related

operator does not exist: # timestamp without time zone

In a parameterized query issued from c# code to PostgreSQL 10.14 via dotConnect 7.7.832 .NET connector, I select either a parameter value or the local timestamp, if the parameter is NULL:
using (var cmd = new PgSqlCommand("select COALESCE(#eventTime, LOCALTIMESTAMP)", connection)
When executed, this statement throws the error in subject. If I comment out the corresponding parameter
cmd.Parameters.Add("#eventTime", PgSqlType.TimeStamp).Value = DateTime.Now;
and hardcode
using (var cmd = new PgSqlCommand("select COALESCE('11/6/2020 2:36:58 PM', LOCALTIMESTAMP)", connection)
or if I cast the parameter
using (var cmd = new PgSqlCommand("select COALESCE(cast(#eventTime as timestamp without time zone), LOCALTIMESTAMP)", connection)
then it works. Can anyone explain what # operator in the error is referring to and why the error?
In the case that doesn't work, your .Net connection library seems to be passing an SQL command containing a literal # to the database, rather than substituting it. The database assumes you are trying to use # as a user defined operator, as it doesn't know what else it could possibly be. But no such operator has been defined.
Why is it doing that? I have no idea. That is a question about your .Net connection library, not about PostgreSQL itself, so you might want to add tag.
The error message you get from the database should include the text of the query it received (as opposed to the text you think it was sent) and it is often useful to see that in situations like this. If that text is not present in the client's error message (some connection libraries do not faithfully pass this info along) you should be able to pull it directly from the PostgreSQL server's log file.

Input string was not in correct formate while inserting data to postgresql through entityframework in .net core using dynamic query

I am getting error while inserting data to pgsql with .net core entity framework
error is Input string was not in correct format
this is my query executing
INSERT INTO public."MedQuantityVerification"("Id","MedId","ActivityBy","ActivityOn","Quantity","ActivityType","SupposedOn","Note") Values(7773866,248953,8887,'7/14/2018 10:43:43 PM','42.5 qty',5,NULL,'I counted forty two {point} five.')
anyhow when I run that query directly to postgresql browser it works fine
looks like issue on c# side it is but not know what?
also issue is with {point}
this is how I executing the dynamic query
db.Database.ExecuteSqlRaw(query);
You have to escape the curly brackets:
{point} should be {{point}}
ExecuteSqlRaw utilizes curly braces to parameterize the raw query so if your query naturally includes them like OP's does the function is going to try and parse them. Doubling up the braces like in Koen Schepens' answer acts as an escape sequence and tells the function not to parse it as a parameter.
The documentation for the function uses the following example as to the purpose of why it does what it does:
var userSuppliedSearchTerm = ".NET";
context.Database.ExecuteSqlRaw("UPDATE Blogs SET Rank = 50 WHERE Name = {0}", userSuppliedSearchTerm);
Note that you'll want to use this to your advantage any time you're accepting user-input and passing it to ExecuteSqlRaw. If the curly brace is in a parameter instead of the main string it doesn't need to be escaped.

How to connect to DB2 from Lotus Notes Client via LotusScript?

Just simple using JDBC driver in Java agent works fine. Now I need to connect DB2 from LotusScript. There are many articles like those:
http://www.proudprogrammer.no/web/ppblog.nsf/d6plinks/GANI-9DFMRB
https://openntf.org/XSnippets.nsf/snippet.xsp?id=db2-run-from-lotusscript-into-notes-form
but they use ODBC connection or something else. Anyway I don't see where I can define DB2 host and port in my LotusScript agent. Users won't be able to configure ODBC connection on each workstation. I need some Domino native method to connect to DB2. Or where do I define DB2 host/IP and port in this example:
https://openntf.org/XSnippets.nsf/snippet.xsp?id=db2-run-from-lotusscript-into-notes-form
You could use LSXODBC library but that is deprecated so you probably shouldn't.
The current supported method is to use the LSXLC library but be warned that it provides a very OO-centric approach to sending/consuming data but it is very quick and if you use it as designed, can make moving data from one data provider (say Notes) to another (say DB2) somewhat easy.
If you want to stick with standard SQL strings you can still do that with LSXLC with the "execute" method off of the LSConnection object.
As far as connecting to it goes you just need to make sure the appropriate driver is installed on the machine and then use the appropriate connection parameter in the when creating a new LSConnect object (e.g., ODBC2 for ODBC, DB2 for the CLI DB2 driver, OLEDB for an SQL OLE driver, etc).
If you stick with ODBC or OLEDB you can control the connection string via code. If you use the CLI DB2 driver (which is very, very fast) you need to configure the connection on each machine the driver is installed on.
All this is documented in the Designer help but it is, in my opinion, not organized in the best fashion. But it is all there.
So, some example code that has been largely copied from some code I have sitting around and is not tested is:
Option Declare
UseLSX "*lsxlc"
Sub Initialize
Dim LCSession As LCSession
Dim lcRDBMS As LCConnection
dim lcFieldList as new LCFieldList()
dim lcField_FirstName as LCField
dim lcField_LastName as LCField
dim strFirstName as string
dim strLastName as string
dim strConnectionType as string
' Hard-coding this here just for this example
' I think you will either want an ODBC (odbc2) or a CLI DB2 (db2) connection
strConnectionType = "odbc2"
Set lcRDBMS = New LCConnection (strConnectionType)
' Set some standard properties on the LCConnection object
lcRDBMS.Userid="<userid>"
lcRDBMS.Password="<password>"
lcRDBMS.MapByName=True
' Properties and property values that are different
' depending on the connection type
select case strConnectionType
case "odbc2" :
' Use the DSN name as configured in the ODBC Control Panel (if on Windows)
lcRDMBS.Database = "<SYSTEMDSN>"
case "oledb" :
lcRDBMS.Server = "<myserver.company.net>"
lcRDBMS.Provider = "sqloledb"
lcRDBMS.Database = "<my_database_name>"
' Not sure this actually changes anything or is even setting the correct property
' But the intent is to make sure the connection to the server is encrypted
lcRDBMS.INIT_ProviderString = "ENCRYPT=TRUE"
case "db2" :
' I am afraid I have lost the connection properties we used to use
' to form up a DB2 CLI connection so the following is just a best guess
' But if you are not going to be using the advance features of LSX to
' connect to DB2 you might as well just a standard ODBC driver/connection
lcRDBMS.Database = "<connection_name>"
End Select
Call lcRDBMS.Connect()
' This call returns a status code and populate the lcFieldList object with our results
lngQueryStatus = LcRDBMS.Execute("<Select FirstName, LastName from SCHEMA.Table WHERE blah>", lcFieldList)
If lngQueryStatus <> 0 Then
If lcFieldList_Destination.Recordcount > 0 Then
' Get our fields out of the lcFieldList object before going into the loop.
' Much more performant
Set lcField_FirstName = lcFieldList.Lookup("FirstName")
Set lcField_LastName = lcFieldList.Lookup("LastName")
While (lcConn.Fetch(lcFieldList) > 0 )
strFirstName = lcField_FirstName.Text(0)
strLastName = lcField_LastName.Text(0)
' Do something here with values
Wend
End If
End If
End Sub

Setting application_name on Postgres/SQLAlchemy

Looking at the output of select * from pg_stat_activity;, I see a column called application_name, described here.
I see psql sets this value correctly (to psql...), but my application code (psycopg2/SQLAlchemy) leaves it blank.
I'd like to set this to something useful, like web.1, web.2, etc, so I could later on correlate what I see in pg_stat_activity with what I see in my application logs.
I couldn't find how to set this field using SQLAlchemy (and if push comes to shove - even with raw sql; I'm using PostgresSQL 9.1.7 on Heroku, if that matters).
Am I missing something obvious?
the answer to this is a combination of:
http://initd.org/psycopg/docs/module.html#psycopg2.connect
Any other connection parameter supported by the client library/server can be passed either in the connection string or as keywords. The PostgreSQL documentation contains the complete list of the supported parameters. Also note that the same parameters can be passed to the client library using environment variables.
where the variable we need is:
http://www.postgresql.org/docs/current/static/runtime-config-logging.html#GUC-APPLICATION-NAME
The application_name can be any string of less than NAMEDATALEN characters (64 characters in a standard build). It is typically set by an application upon connection to the server. The name will be displayed in the pg_stat_activity view and included in CSV log entries. It can also be included in regular log entries via the log_line_prefix parameter. Only printable ASCII characters may be used in the application_name value. Other characters will be replaced with question marks (?).
combined with :
http://docs.sqlalchemy.org/en/rel_0_8/core/engines.html#custom-dbapi-args
String-based arguments can be passed directly from the URL string as query arguments: (example...) create_engine() also takes an argument connect_args which is an additional dictionary that will be passed to connect(). This can be used when arguments of a type other than string are required, and SQLAlchemy’s database connector has no type conversion logic present for that parameter
from that we get:
e = create_engine("postgresql://scott:tiger#localhost/test?application_name=myapp")
or:
e = create_engine("postgresql://scott:tiger#localhost/test",
connect_args={"application_name":"myapp"})
If you're using asyncpg driver, you should use
conn = await asyncpg.connect(server_settings={'application_name': 'foo'})
src - https://github.com/MagicStack/asyncpg/issues/204#issuecomment-333917251

How to handle backslash(\) in ENCRYPE/DECRYPT

I m using a update Query.
i.e:-
UPDATE tbl_ecpuser
SET ecpuser_fullname = 'Operator',
ecpuser_password = encrypt(E'Op1111/1\1/1\1' , 'ENCRYPE_KEY', 'ENCRYPE_ALGORITHM'),
where ecpuser_key = '0949600348'
Query is Executing Successfully.
But when I m trying to retrive the value for the Column ecpuser_password, it
returns with some extra character (i.e-00)
The Query for the Retrive the Password is:-
SELECT
decrypt(ecpuser_password,'ENCRYPE_KEY','ENCRYPE_ALGORITHM') AS PASSWORD
FROM tbl_ecpuser
WHERE
ecpuser_key = '0949600348'
This query returens
"Op1111/1\001/1\001"
but it should return "Op1111/1\1/1\1" and I need this.
So can any body help me about this.
Thanks.
One place where PostgreSQL was not conforming to the SQL standard was the treatment of a backslash in string literals.
Since 8.2 a configuration property standard_conforming_strings is available that configures PostgreSQL to comply with the standard here.
If you set that to "on" '\1' is treated correctly as a string with two characters (one backslash and the character 1).
However if that is turned on, the prefix E enables escape sequences again.
So (if I understand your problem correctly) you should set standard_conforming_strings = on and specify the string literal without the leading E.
Seems like E'\1' is treated as chr(1) and returned accordingly.
You probably want: E'\\1'.