Why different speed between oracle and postgresql? - oracle

In postgresql
select * from test where text123 = '1'
"Index Scan using ix_test on test (cost=0.57..12619.44 rows=6980 width=343)"
" Index Cond: ((text123)::text = '1'::text)"
select * from test where text123 = ''
"Seq Scan on test (cost=0.00..11918891.20 rows=209355618 width=343)"
" Filter: ((text123)::text = ''::text)"
first query result returns immediately. but second isn't.
In Oracle, it has same plan with postgresql but second query result returns immediately.
What can I do for second query in postgresql?
And why second query is so slow?
please help me...

The second query
select * from test where text123 = ''
does very different things in PostgreSQL and Oracle.
In PostgreSQL '' means "a string of zero length". Thus in PostgreSQL the query means
Return all fields in all rows of table test where the text123 column
is equal to a string which is zero characters long
In Oracle, however '' means NULL. Thus in Oracle this query means
Return all fields in all rows of table TEST where the TEXT123 column
is equal to NULL
and because nothing, not even NULL, is ever equal to NULL the query will return nothing.
Best of luck.

Related

Retrieving data from oracle table using scala jdbc giving wrong results

I am using scala jdbc to check whether a partition exists for an oracle table. It is returning wrong results when an aggregate function like count(*) is used.
I have checked the DB connectivity and other queries are working fine. I have tried to extract the value of count(*) using an alias, But it failed. Also tried using getString. But it failed.
Class.forName(jdbcDriver)
var connection = DriverManager.getConnection(jdbcUrl,dbUser,pswd)
val statement = connection.createStatement()
try{
val sqlQuery = s""" SELECT COUNT(*) FROM USER_TAB_PARTITIONS WHERE
TABLE_NAME = \'$tableName\' AND PARTITION_NAME = \'$partitionName\' """
val resultSet1 = statement.executeQuery(sqlQuery)
while(resultSet1.next())
{
var cnt=resultSet1.getInt(1)
println("Count="+cnt)
if(cnt==0)
// Code to add partition and insert data
else
//code to insert data in existing partition
}
}catch(Exception e) { ... }
The value of cnt always prints as 0 even though the oracle partition already exists. Can you please let me know what is the error in the code? Is this giving wrong results because I am using scala jdbc to get the result of an aggregate function like count(*)? If yes, then what would be the correct code? I need to use scala jdbc to check whether the partition already exists in oracle and then insert data accordingly.
This is just a suggestion or might be the solution in your case.
Whenever you search the metadata tables of the oracle always use UPPER or LOWER on both side of equal sign.
Oracle converts every object name in to the upper case and store it in the metadata unless you have specifically provided the lower case object name in double quotes while creating it.
So take an following example:
-- 1
CREATE TABLE "My_table_name1" ... -- CASE SENSISTIVE
-- 2
CREATE TABLE My_table_name2 ... -- CASE INSENSITIVE
In first query, we used double quotes so it will be stored in the metadata of the oracle as case sensitive name.
In second query, We have not used double quotes so the table name will be converted into the upper case and stored in the metadata of the oracle.
So If you want to create a query against any metadata in the oracle which include both of the above cases then you can use UPPER or LOWER against the column name and value as following:
SELECT * FROM USER_TABLES WHERE UPPER(TABLE_NAME) = UPPER('<YOUR TABLE NAME>');
Hope, this will help you in solving the issue.
Cheers!!

Merge with dual not working in 12c

Hi I am using Oracle 12c and I have executed the below query which returns 0 rows merged. Please advise if I am doing something wrong.
The table cons_temp contains two columns,
name, value.
merge into cons_temp tb
using (select 'Freez' as NAME, 'NOI' as VALUE from dual where 1=2) v
on (tb.NAME=v.NAME)
when matched then update set tb.VALUE=v.VALUE
when not matched then insert (NAME,VALUE) values(v.NAME, v.VALUE);
Why have you put this line in the USING query?
where 1=2
That will always evaluate to false (because 1 != 2). Consequently your USING query will return zero rows, so there is nothing to match or unmatch.
If you remove that WHERE clause your statement will do something.

Oracle no index for function calls in sql query

I have a table with name t(abc varchar2(50),xyz varchar2(50), ..etc) and index enabled on column abc. Oracle uses the index for userfunction(a) which takes long time. This is a dynamic query formed can have another conditions that must use index on abc so I don't want to use no_index hint.
select *from t
where
userfunction(a) = 0
and exists (select 1 from tab where t.abc='' ...etc)
and ..etc
I tried to re-write the query with nested query by moving the function to nested query, but oracle is re-writing and still executing userfunction(a) at the first and the query is taking long time.
select *from (
select *from t
where
and exists (select 1 from tab where t.abc='' ...etc)
..etc
)
userfunction(a) = 0
Also tried using WITH clause but no luck.
Any idea of oracle not to use index for user function calls or certain condition in where clause?
Your query is not logically consistent: you reference table t and tab, but only desribe t. Assuming you meant t when you wrote tab, I can't see why you need the exists clause with a sub-query. EXISTS will just return TRUE when the expression in the subselect evaluates to TRUE; so why not just use that expression in the main query on t?

Make condition only if "something" - Query Oracle

i'm with a problem in a query.
I have a table called "store" that I need to query.
Select s.store_name
from store s
where s.store = case
when p_store != 0 then
p_store
else
s.store
end;
This should work but as I have "stores" with characters (-) in column and this is defined as number, that query raise an exception: ORA-01722: invalid number.
So I want to do something like this in query:
IF p_store != 0 then
select store_name from store where store = p_store
else
select store_name from store;
Is it possible?
Thanks!
EDIT:
The query that I wrote above was an example of the query I was running.
The exception was raised because another column (too much hours in front of PC :-( ).
This table have a column that's varchar2(15) and I was doing this condition:
(...)AND S.CODE > 4 (...)
The correct condition that I want to do is:
(...)AND LENGTH(S.CODE) > 4
Thank you all!
As far as I understand you have varchar2 s.store which in fact contains numbers so Oracle tries to compare it casting to numbers but at some point it gets - and throws an exception. What you should do is update on table replacing - by null. But if you don't want to do that you can try to make case return varchar2
Select s.store_name
from store s
where s.store = case
when to_char(p_store) != '0' then
to_char(p_store)
else
s.store
end;
I am guessing you are running the query in a plsql block (as cursor?). In that case dynamic sql is the way to go. check out REF CURSOR too (google!).

Oracle AWR - high SQL Parse Calls but 0 Executions

I'm trying to understand what is causing an open query on an Oracle (10) database.
On AWR it shows a very high number of parse calls (e.g. 15,000+ in a 1 hour period), but 0 executions.
How it can the query not be executed, but then parsed 15000 times?
Parse Calls : 15,000+
Executions : 0
SQL Text : select * from AVIEW
The * in the SQL would explain the repeated parsing. You should replace it with a list of field names.
Oracle 11, java, jdbc 11.2.0.3
Problem occurs when you getting sequence from insert like this
PreparedStatement ps = connection.prepareStatement(QUERY, new String[] { "student_id" });
We found that jdbc driver prepares "SELECT * FROM " statement before every insert. There is only parse operation without execution.
T4CConnection.doDescribeTable
T4CStatement localT4CStatement = new T4CStatement(this, -1, -1);
localT4CStatement.open();
String str1 = paramAutoKeyInfo.getTableName();
String str2 = new StringBuilder().append("SELECT * FROM ").append(str1).toString();
localT4CStatement.sqlObject.initialize(str2);
Oracle parser doesn't cache parsed queries with "*" so there is additional parse operation per every insert.
Zero executions indicates that the query did not complete within the AWR snapshot
We have a similar issue, but the query was slightly different:
select col1, col2, col3 from table
Result was the same. A high parse rate but zero executions.
The reason was StatementCreatorUtils#setNull from spring-jdbc. ver 4.2.7
When executing:
insert into table (col1, col2, col3) values (val1, null, null)
there was a call to the database for a parameter type.

Resources