Custom Exception Handling on Select Query - oracle

I'v been looking around, and not able to find anything helpful in my specific situation. I'm attempting to debug a query that I have limited access to. I cannot access the database itself, but I can query the database.
The query is something along the lines of
SELECT col1, col2, col3 FROM table WHERE col1 = TRUNC(:varibleName)
I am fairly sure the :variableName is being sent as a date+time, and col1 is a date column. However, I get the error, "Expected Date, got Number".
What I would like to do is see what the value of :variableName is when being run in this query. I have been attempting to find out by using custom exception handling but it doesn't seem like I can run a simple query.
Is there any way I can see the value of the variable when it causes an error?

You may use TO_DATE and pass variable in a particular format.
SELECT col1, col2, col3
FROM table WHERE col1 = TRUNC(:to_date(:varibleName,'yyyy-mm-dd'))
Now, you can pass a string like 2019-09-01 , 2019-07-20 etc.

Add-on to Kaushik,
Query:
To replicate the error:
Error:ORA-00932: inconsistent datatypes: expected DATE got NUMBER
with cte as (select trunc(sysdate) as dt, sysdate-1 as yst_dt from dual)
select * from cte where dt=TRUNC(2019-07-18) ;
By using To_Date format:
with cte as (select trunc(sysdate) as dt, sysdate-1 as yst_dt from dual)
select * from cte where dt=TRUNC(to_date('2019-07-18','yyyy-mm-dd')) ;

Related

How to return distinct values in a JSON_ARRAYAGG

So I'm attempting to place the results of a distinct, single-column query into a JSON array so it can be used on my web server. I have it set up something like this:
SELECT JSON_OBJECT(
'ArrayKey' VALUE JSON_ARRAYAGG( col )
) AS jsonResult
FROM(SELECT DISTINCT column_name AS col
FROM tbl_name);
However, when this query returns results, the array it generates in JSON contains all values from my column and ignores the DISTINCT clause in the subquery somehow. Whenever I get rid of the JSON_ARRAYAGG clause and output the results directly, the result are unique, but somehow the command is ignored when I add it back in. I've also attempted to place the DISTINCT clause inside the JSON_ARRAYAGG as well, like so:
SELECT JSON_OBJECT(
'ArrayKey' VALUE JSON_ARRAYAGG( DISTINCT col )
) AS jsonResult
FROM(SELECT DISTINCT column_name AS col
FROM tbl_name);
to no avail. Does anyone know what's going wrong in my code that's causing the array to output all values instead of distinct ones?
Interesting... Looks like a bug to me. The optimizer seems to push down too eagerly.
As workaround you can use the NO_MERGE hint on the subquery.
SELECT /*+NO_MERGE(x)*/
json_object('ArrayKey'
VALUE json_arrayagg(column_name)) jsonresult
FROM (SELECT DISTINCT
column_name
FROM tbl_name) x;
A CTE and a MATERIALIZE hint seem to work too.
WITH cte
AS
(
SELECT /*+MATERIALIZE*/
DISTINCT
column_name
FROM tbl_name
)
SELECT json_object('ArrayKey'
VALUE json_arrayagg(column_name)) jsonresult
FROM cte;
db<>fiddle
This was a bug, we fixed it. You can try it out on live SQL
create table tbl_name (column_name number);
insert into tbl_name values(1);
insert into tbl_name values(1);
insert into tbl_name values(2);
SELECT JSON_OBJECT(
'ArrayKey' VALUE JSON_ARRAYAGG( col )
) AS jsonResult
FROM(SELECT DISTINCT column_name AS col
FROM tbl_name);
{"ArrayKey" : [1,2]}
The bug is
Bug 27757725 - JSON GENERATION AGGREGATION FUNCTIONS IGNORE DISTINCT
you can request a backport from Oracle Support Services
I've found this hack to work:
SELECT JSON_OBJECT(
'ArrayKey' VALUE JSON_ARRAYAGG( col )
) AS jsonResult
FROM(SELECT DISTINCT column_name AS col
FROM tbl_name)
HAVING COUNT(*) = COUNT(*);
See also: Oracle bug produces duplicate aggregate values in JSON_ARRAYAGG

ORA-01722: invalid number but only when query used as subquery

A query, like so:
SELECT SUM(col1 * col3) AS total, col2
FROM table1
GROUP BY col2
works as expected when run individually.
For reference:
table1.col1 -- float
table1.col2 -- varchar2
table1.col3 -- float
When this query is moved to a subquery, I get an ORA-01722 error, with reference to the "col2" position in the select clause. The larger query looks like this:
SELECT col3, subquery1.total
FROM table3
LEFT JOIN (
SELECT SUM(table1.col1 * table1.col3) AS total, table.1col2
FROM table1
GROUP BY table1.col2
) subquery1 ON table3.col3 = subquery1.col2
For reference:
table3.col3 -- varchar2
It may also be worth noting that I have another query, from table2 that has the same structure as table1. If I use the subquery from table2, it works. It never works when using table1.
There is no concatenation, the data types match, the query works by itself... I'm at a loss here. What else should I be looking for? What painfully obvious problem is staring me in the face?
(I didn't choose or make the table structures and can't change them, so answers to that end will unfortunately not be helpful.)
try using a proper cast of float to char ..
SELECT col3, subquery1.total
FROM table3
LEFT JOIN (
SELECT SUM(table1.col1 * table1.col3) AS total, table.1col2
FROM table1
GROUP BY table1.col2
) subquery1 ON to_char(table3.col3) = subquery1.col2

Use sequence number with insert select

I'm trying to execute the following statement:
INSERT INTO mySchema.ODI_PRICELIST_THREAD_TABLE
(
src_table,
thread_id,
creation_date
)
SELECT DISTINCT
source_table AS src_table,
num_thread_seq.nextval AS THREAD_ID,
create_date AS CREATION_DATE
FROM mySchema.nb_pricelist_ctrl
I need the THREAD_ID field to be a number from 1 to X where X is defined in runtime therefore I've used a sequence from 1 to X (I'm using ODI).
However, I keep having the ORA-02287 Sequence not allowed error...
I've read this question and I still can't figure how I can fix my problem.
I've been seaching but I'm having no luck with finding a solution. Please help
Keyword distinct is incompatible with sequence querying. If you really need it, try something like
INSERT INTO mySchema.ODI_PRICELIST_THREAD_TABLE (
src_table,
thread_id,
creation_date)
select
a.src_table,
num_thread_seq.nextval,
a.create_date
from
(select distinct src_table, create_date from mySchema.nb_pricelist_ctrl) a
From OraFaq :
The following are the cases where you can't use a sequence:
For a SELECT Statement:
In a WHERE clause
In a GROUP BY or ORDER BY clause
In a DISTINCT clause
Along with a UNION or INTERSECT or MINUS
In a sub-query
http://www.orafaq.com/wiki/ORA-02287
Try this
INSERT INTO mySchema.ODI_PRICELIST_THREAD_TABLE
(
src_table,
thread_id,
creation_date
)
SELECT DISTINCT
source_table AS src_table,
num_thread_seq.nextval() AS THREAD_ID,
create_date AS CREATION_DATE
FROM mySchema.nb_pricelist_ctrl

ORA-00918: column ambiguously defined: how to find the column

I'm getting the classic error:
ORA-00918: column ambiguously defined
Usually, I know how to solve it but my problem now is that I'm working with a 700 row query.
Is there a way to identify the column?
Have you tried to do a binary search?
e.g.
If your original query looks like
Select col1
,col2
,col3
,col4
from MyTable
you can start with commenting the 2nd half
Select col1
,col2
/*,col3
,col4 */
from MyTable
If you still get the error, run the query again commenting some column from the other half:
Select col1
/*,col2 */
,col3
,col4
from MyTable
If you still get an error then your problem is with col1, otherwise you need to change col2.
The ambiguous column error message indicates that you have joined two (or more) columns in your query which share the same column name.
The proper way to solve this is to give each table in the query an alias and then prefix all column references with the appropriate alias. I agree that won't be fun for such a large query but I'm afraid you will have to pay the price of your predecessor's laxness.
In Oracle, you can use all_tab_cols to query the columns names of your tables. The following query will return the common column names between TABLE1 and TABLE2. Then you just need to prefix those common columns instead of all 100 column references.
select column_name from all_tab_cols
where table_name='TABLE1' and owner ='OWNER1'
and column_name in (
select column_name from all_tab_cols
where table_name='TABLE2' and owner ='OWNER2')
For posterity's sake:
I had this issue when I selected columns TABLE1.DES and TABLE2.DES in a query without aliasing the result. When I ran it alone my SQL editor turned these into DES and DES_1, no complaint.
However when I turned the same query into a subquery
SELECT a.col1, a.col2, a.col3, b.*
from TABLE3 a
INNER JOIN (
--that query as a subquery
) b
on a.PK=b.FK`
it threw the same ORA-00918 error message you described. Changing the SELECT in my subquery to
SELECT TABLE1.DES AS T1_DES, TABLE2.DES AS T2_DES ...
fixed the issue.
you can check common columns by using :
select COLUMN_NAME from ALL_TAB_COLS where TABLE_NAME = 'tablenamefirst'
intersect
select COLUMN_NAME from ALL_TAB_COLS where TABLE_NAME = 'tablenamesecond';

Getting Error in query

update tablename set (col1,col2,col3) = (select col1,col2,col3 from tableName2 order by tablenmae2.col4) return error
Missing ). The query works fine if I remove the order by clause
ORDER BY is not allowed in a subquery within an UPDATE. So you get the error "Missing )" because the parser expects the subquery to end at the point that you have ORDER BY.
What is the ORDER BY intended to do?
What you probably have in mind is something like:
UPDATE TableName
SET (Col1, Col2, Col3) = (SELECT T2.Col1, T2.Col2, T2.Col3
FROM TableName2 AS T2
WHERE TableName.Col4 = T2.Col4
)
WHERE EXISTS(SELECT * FROM TableName2 AS T2 WHERE TableName.Col4 = T2.Col4);
This clumsy looking operation:
Grabs rows from TableName2 that match TableName on the value in Col4 and updates TableName with the values from the corresponding columns.
Ensures that only rows in TableName with a corresponding row in TableName2 are altered; if you drop the WHERE clause from the UPDATE, you replace the values in Col1, Col2, and Col3 with nulls if there are rows in TableName without a matching entry in TableName2.
Some DBMS also support an update-join notation to reduce the ghastliness of this notation.

Resources