What does double question mark (??) mean in sql (postgres sql) - sql

What does double question mark (??) mean in sql or sql query. (postgres sql).
My DB Server is Postgres and I am using columns that are of type jsonb.
I see a query that has ?? in it. Below is the query.
select rr.jdoc
from table_with_jsonb rr
where not (rr.jdoc ?? 'pivot')
and ((rr.jdoc->'mapping'->>'objectType')<>'meta');
Can some one explain what the ?? means and any references will be of great help.
Normally my understand is that - ? is to allow Parameterized Query.
But this table 9.4 ref -> FUNCTIONS-JSONB-OP-TABLE or 13.x ref -> FUNCTIONS-JSONB-OP-TABLE adds more usage scenerios for ?.
But still it does not say what ?? is.
PS: Plz ignore the doc references to 9.4. I am using 13.x currently.

It's the same as the ? operator when used through JDBC.
JDBC uses ? for parameter placeholders and thus there needs to be a way to distinguish the operator from the parameter placeholder. So the Postgres JDBC driver allows to escape the ? operator using ?? in a PreparedStatement.
I don't know if other technologies (ODBC, .Net) are using a similar mechanism.

Related

HSQLDB MySQL compatibility is rubbish

With reference to http://hsqldb.org/doc/2.0/guide/compatibility-chapt.html#coc_compatibility_mysql, the compatibility only solves half the problem. THE CAPITALIZED RESULTSETMETADATA (COLUMN NAMES) IS A PROBLEM! This complicates testing with the in-memory database when the MySQL is used in production. I have to sprinkle code in my controllers / verticles to check which database is used (test or non-test) and format the SQL query string by double-quoting the column names in the query.
Related post: Java common JDBC SQL Query strategy for Unit Test using HSQLDB and runtime using MySQL
Question: How to use lower-case column names or how to convert the capitalized RESULTSETMETADATA returned from HSQLDB to lower case?
Solution: Ditch HSQLDB and use H2 with database_to_upper=false option.

jOOQ MERGE support for PostgreSQL conditional insert

I had understood that jOOQ would simulate SQL MERGE on systems (such as PostgreSQL) that don't support it.
I have a table with a serial (autoincrement) "id" column and a string "uri" column. I want to use numeric IDs instead of URIs in my database, so I have to make sure I have a URI in the ID lookup table. So following the example in the jOOQ manual, I thought this would work:
createDSLContext().mergeInto(tableByName("uris"))
.using(createDSLContext().selectOne())
.on(fieldByName("uri").equal("http://example.com/"))
.whenNotMatchedThenInsert(fieldByName("uri"))
.values("http://example.com/").execute();
This gives me a DataAccessException saying something like:
SQL [merge into "uris" using (select 1) on "uri" = ? when not matched then insert ("uri") values (?)]; ERROR: syntax error at or near "merge"
But then the log says jOOQ goes ahead and tries to execute the query with bind values. But the table is never updated. So I'm guessing the jOOQ doesn't simulate MERGE on PostgreSQL?
So I then try the H2 database syntax:
createDSLContext().mergeInto(tableByName("uris"), fieldByName("uri")).values(uri.toString()).execute();
I get:
The H2-specific MERGE syntax is not supported in dialect : POSTGRES
What!? But the jOOQ documentation says that the H2 syntax "can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
To be sure if a given SQL feature is supported by jOOQ for your database, please consider the Javadoc's #Support annotation on the relevant DSL method. This is also documented in the manual. In this case, DSLContext.mergeInto(), where you can see that this statement is currently only supported for these SQLDialects:
#Support(value={CUBRID,DB2,HSQLDB,ORACLE,SQLSERVER,SYBASE})
MERGE is a very powerful statement that is not really easy to emulate if your database doesn't natively support it.
"can be fully simulated by jOOQ for all other databases that support the SQL standard." Surely PostgreSQL supports the SQL standard. Does it really mean "...the SQL standard version of MERGE?"
Yes of course, the SQL standard MERGE statement must be supported :-) We'll clarify this in the manual. I have registered issue #3183 for this.
Is there any way to get PostgreSQL support for MERGE via jOOQ, or am I stuck doing the same workarounds I would do anyway?
Right now, unfortunately, we don't have a solution for this in PostgreSQL. Feel free to discuss possible solutions on the jOOQ User Group.
Yes , it can support which database support the merge in SQL stand.
but postgresql unsupport this feature in SQL standard.
Please see
F312 MERGE statement
F313 Enhanced MERGE statement
F314 MERGE statement with DELETE branch
http://www.postgresql.org/docs/9.3/static/unsupported-features-sql-standard.html

what is the difference between SUBSTRING and SUBSTR functions (SQL)?

before I used :
entityManagerFactory.createQuery("select p FROM Pays p where SUBSTRING(p.libeleClient, 0,1)
but when I use this query :
entityManagerFactory.createQuery("select p FROM Pays p where SUBSTR(p.libeleClient, 0,1)
I get an exception :(
who to remplace SUBSTRING by SUBSTR ?
SUBSTR is the function from Oracle
SUBSTRING is the function from MySql
depends on DB which u r using
EDIT:
try to edit your java code like below
String query = "select p FROM Pays p where SUBSTRING(p.libeleClient, 0,1)";
// from Connection Object (connection)
DatabaseMetaData meta = connection.getMetaData();
//If the DB is Oracle
if(meta.getDatabaseProductName()).contains("Oracle")) {
entityManagerFactory.createQuery(query.replace("SUBSTRING", "SUBSTR"));
}// If the DB not Oracle , any Other like MySql
else {
entityManagerFactory.createQuery(query);
}
substring is the sql operation defined in the sql standard ISE:IEC 9075:1992.
substr is an old syntax used by oracle. This wrong syntax is completely inconsistent with sql usage of real english words, never abbreviations.
Oracle still does not support the standard syntax.
Did anyone wrote a hack in oracle to support the standard syntax ?
You don't say what exception you get, but I 'm guessing it's a syntax error. The correct syntax for Oracle's SUBSTR() is ...
where SUBSTR(p.libeleClient, 0,1) = 'X'
...(or whatever). That is the first occurence of a single character must equal; some specified value. SUBSTR() is not a boolean function.
Whereas SUBSTRING() is not an oracle function at all. Either you've borrowed the syntax from some other database, or you're using a bespoke function without realising it.
"I tried your suggestion but it does not work"
Do you get an error? Or do you mean it doesn't return any records? Because I have given a perfectly valid usage, as defined in the documentation. But you haven't given any examples of your data, so it's almost impossible for me to provide a solution which will return rows from your database.

Dynamically building WHERE clauses in SQL statements

I have a question regarding SQL. I have the following SQL statement:
SELECT id, First, Last, E_Mail, Notes
FROM mytable
WHERE SOMETHING_SHOULD_BE_HERE IS NOT NULL;
I know that the SOMETHING_SHOULD_BE_HERE should be a column(attribute) in my table. Is their a way I can put a variable that can refer to the column I'm trying to access? In my case their are 30 columns. Can I have a string for SOMETHING_SHOULD_BE_HERE that can be assigned in my program to the column in which I want to search?
Thanks
No. Variables in SQL can refer to data, but not to object names (columns, functions or other database objects).
If you are building the SQL query, you'll need to use string operations to build your query.
The column can't be variable, but the value of the column can. The parser needs to know what to bind to.
If you elaborate on what you're trying to solve and which platform you're using it would allow for more complete answers.
You can have different SQLs queries in your code and use each one according to the case.
Another way is generate dynamically the query according the fields you want.
Without dynamic SQL, this is probably your best bet:
SELECT
id, first, last, email, notes
FROM
My_Table
WHERE
CASE #column_name_variable
WHEN 'column_1' THEN column_1
WHEN 'column_2' THEN column_2
...
ELSE 'not null'
END IS NOT NULL
There might be some issues with data type conversions, so you might need to explicitly cast all of the columns to one data type (VARCHAR is probably the best bet). Also, there's a good chance that performance will be horrendous on this query. I'd test it thoroughly before even thinking about implementing something like this.
I mentioned this in my comment, but for completeness I'll put it here too... you can probably also accomplish this with dynamic SQL, but how you do that will depend on your database server (MS SQL Server, Oracle, mySQL, etc.) and there are usually some caveats to using dynamic SQL.
In JDBC program, yes,the select statement can be composed like string operation.
for(String colName: colList)
{
String sql="Select id, First, Last, E_Mail, Notes From mytable where "+colName+" IS NOT NULL";
//execute the sql statement
}
It depends on how you are going to find out the value of SOMETHING_SHOULD_BE_HERE.
If you are in an Oracle PLS/SQL environment you could build up the WHERE clause using dynamic SQL and then use EXECUTE IMMEDIATE to execute it.
If you have a small set number of possibilities you could use CASE to workaround your problem possibly.
Your question is unclear.
However I am quite sure that what you have in mind is the so-called dynamic SQL (and related). "Dynamic SQL" allows you to dynamically build and submit queries at runtime. However such functionalities may not exist for your RDBMS.
There are several ways to do this.
When your query would return one and only one row
then you have to consider the EXECUTE IMMEDIATE statements (along with sp_executesql in tSQL : http://msdn.microsoft.com/en-us/library/ms188001.aspx ; or the USING clause in PL/SQL : http://docs.oracle.com/cd/B14117_01/appdev.101/b10807/13_elems017.htm to specify a list of input/output bind arguments) and/or PREPARED statements (http://rpbouman.blogspot.fr/2005/11/mysql-5-prepared-statement-syntax-and.html).
When your query can return more than one row
then you have to consider techniques such as the EXECUTE IMMEDIATE statement with the BULK COLLECT INTO clause or the OPEN-FOR, FETCH, and CLOSE statements (explicit cursors in PL/SQL :
http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/dynamic.htm)
Please note that except in some particular cases, most conventional techniques like IF-THEN-ELSE and CASE statements should be preferred (along with a good algorithm). Furthermore they work with almost all RDBMS.

SQL Command ISNULL for ODBC Connection

I'm connected to an OpenEdge DataServer via ODBC (not our product, we are just accessing their database, I hardly have any information and certainly no help from the other side).
Anyhow, I just need to execute a simple Select, add a couple of rows and I need the equivalent of an IsNull statement.
Basically I'd like to execute
SELECT ISNULL(NULL,'test')
This fails with a Syntax Error. I've looked around at something they misleadingly call a "documentation" but there are only references to SP_SQL_ISNULL but I can't get that to work either. I'm fit in T-SQL, so any pointers in any direction appreciated, even if it's just a RTFM with a link to TFM :)
Thanks
Thanks to Catalin and this question I got on the right track. I kept thinking I needed a OpenEdge specific function but actually I needed to use only ODBC SQL syntax.
To get what
ISNULL(col,4)
does you can use
COALESCE(col,4)
which "returns the data type of expression with the highest data type precedence. If all expressions are nonnullable, the result is typed as nonnullable."MSDN
Basically it will convert to 4 if the value is null (and therefore not convertable).
I am not 100% sure, but I think ODBC driver expects a valid SQL statement, and not an DBMS specific SQL statement, like the one you provided.