GROUP BY Nested Table Oracle DB 19 Error ORA-00932 - sql

I have a Data
create or replace NONEDITIONABLE type TST_OBJ force
as table of varchar2(128)
And a table APPS that has a column 'Tst' of TST_OBJ type, as follows:
Column_Name
Type of data
Name
varchar
Tst
TST_OBJ
Offs
number
The issue comes when I try to SELECT and Group By the results as shown next:
select Tst, Offs from APPS group by Tst;
I'm getting error ORA-00932:
ORA-00932: inconsistent datatypes: expected - got TST_OBJ
00932. 00000 - "inconsistent datatypes: expected %s got %s"
*Cause:
*Action:
Is it possible that Group By does not work with this Type of Data or is there a way to achieve it?

Documentation says:
Restrictions on the GROUP BY Clause
This clause is subject to the following restrictions:
You cannot specify LOB columns, nested tables, or varrays as part of expr.
The expressions can be of any form except scalar subquery expressions.
If the group_by_clause references any object type columns, then the query will not be parallelized.
I guess bold part answers your question.
SQL> create or replace type TST_OBJ force
2 as table of varchar2(128);
3 /
Type created.
SQL> create table apps
2 (name varchar2(20),
3 tst tst_obj, --> here it is
4 offs number)
5 nested table tst store as tst_obj_tab;
Table created.
SQL> insert into apps values ('Little', tst_obj('A'), 1);
1 row created.
SQL> insert into apps values ('Foot' , tst_obj('A', 'B', 'C'), 2);
1 row created.
Queries:
SQL> select tst, offs
2 from apps;
TST OFFS
---------------------------------------- ----------
TST_OBJ('A') 1
TST_OBJ('A', 'B', 'C') 2
SQL> select tst, offs, count(*)
2 from apps
3 group by tst, offs;
group by tst, offs
*
ERROR at line 3:
ORA-00932: inconsistent datatypes: expected - got SCOTT.TST_OBJ
SQL>

Related

Converting a date to a number for a Procedure

Hi i have a procedure that has in it
Select
(ROUND(A.START - A.END, 0) AS DAYS_WORKED
FROM WORKINGTABLE A
THIS RETURNS
5
super
when i put it in a procedure and update another table with the DATATYPE as NUMBER the info it says this it cant do it becasue the data type is not a number it is a date. fair enough. so I changed the column to a DATETYPE but it didnt like it and gave an error saying invalid month (as the date and time is 5 im not suppriesed it didnt like it)
so I set the column back to NUMBER
and tried this
TO_NUMBER(ROUND(A.START - A.END, 0))) AS DAYS_WORKED
and this
TO_NUMBER(TO_CHAR(ROUND(A.START - A.END, 0))) AS DAYS_WORKED
but it still thinks it is a date and gives this messag
ORA-00932: inconsistent datatypes: expected NUMBER got DATE.
shows fine in a query output/report it is just the procedure being fussy
any ideas how i can get this to line up?
You did something wrong (can't tell what exactly). Have a look at the following test case.
Sample table; days_worked is - as you said - a number:
SQL> create table test (id number, days_worked number);
Table created.
SQL> insert into test (id) values (1);
1 row created.
Procedure accepts date datatype parameters. Difference of two dates is number of days between.
SQL> create or replace procedure p_test (par_id in number,
2 par_date_start in date, par_date_end in date) is
3 begin
4 update test set
5 days_worked = round(par_date_end - par_date_start, 0)
6 where id = par_id;
7 end;
8 /
Procedure created.
Testing:
SQL> begin
2 p_test(1, to_date('05.12.2022 13:43:22', 'dd.mm.yyyy hh24:mi:ss'),
3 to_date('28.12.2022 08:23:32', 'dd.mm.yyyy hh24:mi:ss'));
4 end;
5 /
PL/SQL procedure successfully completed.
Result:
SQL> select * from test;
ID DAYS_WORKED
---------- -----------
1 23
SQL>
So, yes - it works when properly used.
It turned out it was me not realising how insert into works.
I thought it was inserting on the name of the select, but it wasn't. It was inserting in order of the column (something I can't change in oracle), so when it was saying it was the wrong format, it was because the column it was supposed to be going into wasn't the right one. It ignores the names and does it in order.
Thanks to Lightfoot for pointing me in the right direction.

Issue with Oracle SQL

Can anyone tell me why I'm getting error below:
"ORA-00904: "MESSAGE_BODY": invalid identifier"
When I run below query against an Oracle database?
SELECT COMMERCIAL_ID, MIN(dbms_lob.substr(MESSAGE_BODY, 3999, 1)) AS MESSAGE_BODY
FROM DWH_F_MP_MESSAGE_VW
GROUP BY COMMERCIAL_ID;
MESSAGE_BODY field is a CLOB
It seems that DWH_F_MP_MESSAGE_VW doesn't contain a column named MESSAGE_BODY.
Here's a demonstration:
SQL> create table dwh_f_mp_message_vw (commercial_id number, message_body clob);
Table created.
SQL> insert into dwh_f_mp_message_vw values (1, 'Littlefoot');
1 row created.
SQL> select commercial_id, min(dbms_lob.substr(message_body, 3999, 1))
2 from dwh_f_mp_message_vw
3 group by commercial_id;
COMMERCIAL_ID
-------------
MIN(DBMS_LOB.SUBSTR(MESSAGE_BODY,3999,1))
--------------------------------------------------------------------------------
1
Littlefoot
SQL> select commercial_id, min(dbms_lob.substr(message_bodyyyyyy, 3999, 1))
2 from dwh_f_mp_message_vw
3 group by commercial_id;
select commercial_id, min(dbms_lob.substr(message_bodyyyyyy, 3999, 1))
*
ERROR at line 1:
ORA-00904: "MESSAGE_BODYYYYYY": invalid identifier
SQL>
I suggest you run this:
SQL> desc dwh_f_mp_message_vw
Name Null? Type
----------------------------------------- -------- ----------------
COMMERCIAL_ID NUMBER
MESSAGE_BODY CLOB
and post the result back here (unless you figure it out; in that case, please, explain what went wrong). A possible culprit is a column created under double quotes, e.g.
SQL> drop table dwh_f_mp_message_vw;
Table dropped.
SQL> create table dwh_f_mp_message_vw (commercial_id number, "message_body" clob);
Table created.
SQL> insert into dwh_f_mp_message_vw (commercial_id, message_body) values (1, 'Littlefoot');
insert into dwh_f_mp_message_vw (commercial_id, message_body) values (1, 'Littlefoot')
*
ERROR at line 1:
ORA-00904: "MESSAGE_BODY": invalid identifier
SQL> insert into dwh_f_mp_message_vw (commercial_id, "message_body") values (1, 'Littlefoot');
1 row created.
SQL> desc dwh_f_mp_message_vw
Name Null? Type
----------------------------------------- -------- -------------------
COMMERCIAL_ID NUMBER
message_body CLOB
SQL>
If that's so, get rid of double quotes.

I'm trying to load data into my oracle table using sql loader

This is my table...it has Number as a column name
CREATE TABLE pwc_it_service (
"SEQ" NUMBER,
"NUMBER" VARCHAR2(10),
"CI_NAME" VARCHAR2(200),
"CI_CLASS" VARCHAR2(200),
"OWNED_BY_PRIMARY" VARCHAR2(200),
"OWNED_BY_SECONDARY" VARCHAR2(200),
"MANAGING_TERRITORY" VARCHAR2(200),
"LOS" VARCHAR2(100),
"BUSINESS_UNIT" VARCHAR2(100),
"IMPORTED" DATE,
"LAST_UPDATED" DATE
)
When i run my ctl file, i get the below error:
Record 1: Rejected - Error on table PWC_IT_SERVICE, column NUMBER.
ORA-01747: invalid user.table.column, table.column, or column specification
how can i insert the values without changing column name
It was really a bad idea naming the column "NUMBER" (yes, double quotes and uppercase included). The fact that you can do it doesn't mean that you should do it. Now you have to deal with it and use the same syntax all the time - double quotes and uppercase. Have a look:
SQL> create table test ("NUMBER" varchar2(10));
Table created.
SQL> insert into test (number) values ('A');
insert into test (number) values ('A')
*
ERROR at line 1:
ORA-00928: missing SELECT keyword
SQL> insert into test ("number") values ('A');
insert into test ("number") values ('A')
*
ERROR at line 1:
ORA-00904: "number": invalid identifier
SQL> insert into test ("NUMBER") values ('A');
1 row created.
SQL>
Do the same in the control file.
load data
infile *
replace
into table test
(
"NUMBER" terminated by whitespace
)
begindata
Little
Foot
How it works?
SQL> desc test
Name Null? Type
----------------------------- -------- --------------------
NUMBER VARCHAR2(10)
SQL> $sqlldr scott/tiger#xe control=test02.ctl log=test02.log
SQL*Loader: Release 11.2.0.2.0 - Production on Sri Svi 23 22:23:07 2018
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
Commit point reached - logical record count 1
Commit point reached - logical record count 2
SQL> select * From test;
NUMBER
----------
Little
Foot
SQL>
Works fine.
However, I'd suggest you to rename that unforunate column. Get rid of double quotes, now and forever.

Convert LONG into VARCHAR2 or some text datatype

As we all know LONG is deprecated in Oracle a long back but Oracle itself is still using this datatype in their views.
So if I have to change LONG into some kind of text datatype how can I achieve that.
I am trying to query this and getting error.
ORA-00932: inconsistent datatypes: expected - got LONG
Query -
SELECT NVL(ie.column_expression, ic.column_name)
from user_ind_columns ic left join user_ind_expressions ie on ic.index_name = ie.index_name and ic.table_name = ie.table_name
where ic.table_name = 'Some Table'
There are several methods, one such is create table using TO_LOB. It is designed to convert a LONG or LONG RAW column to a CLOB or BLOB, respectively. Other methods are using PL/SQL, DBMS_XMLGEN. You can also use TO_LOB in insert statements.
Let's see how to convert LONG into CLOB-
SQL> CREATE TABLE t (x INT, y LONG);
Table created.
SQL>
SQL> INSERT INTO t VALUES (1, RPAD('*',9,'!'));
1 row created.
SQL> INSERT INTO t VALUES (2, RPAD('*',9,'#'));
1 row created.
SQL> INSERT INTO t VALUES (3, RPAD('*',9,'#'));
1 row created.
SQL> COMMIT;
Commit complete.
SQL>
So, we have table t with column y s LONG data type.
SQL> CREATE TABLE t1
2 AS
3 SELECT * FROM t
4 /
SELECT * FROM t
*
ERROR at line 3:
ORA-00997: illegal use of LONG datatype
SQL>
We can see the LONG restriction.
Let's use TO_LOB to convert it into CLOB.
SQL> CREATE TABLE t1
2 AS
3 SELECT x,
4 to_lob(y) as y
5 FROM t
6 /
Table created.
SQL> desc t1;
Name Null? Type
----------------------------------------------------- -------- ------------------------------------
X NUMBER(38)
Y CLOB
SQL>
Now you have the same table with the LONG column converted to CLOB.
this is stupid (as in probably not efficient) but it works for samll lengths of y (ie < 2000 characters)..
CREATE TABLE t (x INT, y LONG);
INSERT INTO t VALUES (1, RPAD('*',9,'!'));
CREATE TABLE t1
AS
SELECT x,
regexp_substr(SYS.DBMS_XMLGEN.GETXML('select y from t where rowid = '''||rowid||''''),'<Y>(.*)</Y>',1,1,'in',1) y
FROM t
/
it works by using dbms_xmlgen to generate a clob based on the LONG column.. then substr-ing the value back out.
this only works for small contents of the LONG column. but that is all i had and this worked for me.
I had a similar need, to list the objects and their sizes (including info on columns used in indexes), and came with this solution:
select idx1.table_owner owner, idx1.table_name, idx1.index_name, listagg(nvl(idx1.column_expression,idx1.column_name),',') within group (order by idx1.column_position) column_name
from xmltable(
'/ROWSET/ROW'
passing (select dbms_xmlgen.getxmltype('select ic.table_owner, ic.table_name, ic.index_name, ic.column_position, ic.column_name, ie.column_expression
from all_ind_columns ic
left outer join dba_ind_expressions ie on ie.table_owner=ic.table_owner and ie.table_name=ic.table_name and ie.index_name=ic.index_name and ie.column_position=ic.column_position') from dual)
columns index_name varchar2(30) path 'INDEX_NAME'
, table_owner varchar2(30) path 'TABLE_OWNER'
, table_name varchar2(30) path 'TABLE_NAME'
, column_position number path 'COLUMN_POSITION'
, column_name varchar2(30) path 'COLUMN_NAME'
, column_expression varchar2(4000) path 'COLUMN_EXPRESSION') idx1
group by idx1.table_owner, idx1.table_name, idx1.index_name

Oracle error: character string buffer too small

I am running a basic query that retrieves rows based on basic conditional clauses, nothing complex. This works fine:
<cfquery name="courses" datasource="banner">
SELECT *
FROM tjucatalog
WHERE (course_status = 'Active')
AND CONCAT(subject,course_no) IN (#PreserveSingleQuotes(courselist)#)
AND term IN ('Fall 2012')
AND ((end_date > #now()#) OR (course_meeting_info IS NOT NULL))
ORDER BY TYear, TSort, DayNum, start_date, time, title
</cfquery>
However, when I remove the "AND term IN" line from the query, it fails.
<cfquery name="courses" datasource="banner">
SELECT *
FROM tjucatalog
WHERE (course_status = 'Active')
AND CONCAT(subject,course_no) IN (#PreserveSingleQuotes(courselist)#)
AND ((end_date > #now()#) OR (course_meeting_info IS NOT NULL))
ORDER BY TYear, TSort, DayNum, start_date, time, title
</cfquery>
The error I get is: ORA-06502: PL/SQL: numeric or value error: character string buffer too small ORA-06512: at "BANINST1.TJUCATALOG_PACK", line 519
Is this maybe a view that requires the field 'term' to be included, or is there something else at play here I'm entirely unaware of?
This appears to be an error in a package that's being called under the hood, possibly from a view. You're querying against tjucatalog, and it seems plausible that is a view where one of the returned columns is actually a functional call.
It isn't necessarily the term column that's the problem. By removing that condition, more rows will be returned, and the function is being called against a column value from a row that isn't there when the condition is in place. But it could be any column in one of those now-visible rows.
As a simple and contrived example of what might be happening:
create table t42 (id number, foo varchar2(20));
insert into t42 (id, foo) values (1, 'Short');
insert into t42 (id, foo) values (2, 'More than 10');
create package p42 as
function func(p_id in number) return varchar2;
end p42;
/
create package body p42 as
function func(p_id in number) return varchar2 is
l_bar varchar2(10);
begin
select foo into l_bar from t42 where id = p_id;
return l_bar;
end func;
end p42;
/
create view v42 as select id, p42.func(id) as bar from t42;
So we have a table with two rows, one with a foo less than 10 characters, the other more than 10 characters. We have a (silly) package function that takes an id value, looks up foo, and returns it. And a view that uses that function.
This works:
select * from v42 where id = 1;
ID BAR
---------- --------------------
1 Short
But removing the condition causes it to fail:
select * from v42;
ERROR:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at "SCOTT.P42", line 5
Line 5 of my package body is select foo into l_bar from t42 where id = p_id; and the problem is that I've declare l_bar as varchar2(10), which is too small for the foo value for id=2. I should have declared it as varchar2(20), or even better t42.foo%TYPE.
To see what your problematic function is doing, look at the source code, which you can get from the database (if it isn't wrapped) if you don't have it available:
select line, text from all_source
where owner = 'BANINST1'
and name = 'TJUCATALOG_PACK'
and type = 'PACKAGE BODY'
order by line;
Our Oracle gurus returned and told us they had to change a field type from varchar2 (4000) to CLOB. The lack of the term field as a filter clause was a red herring error. I don't know which field specifically in the query needed to be increased for allowed length, but it works so I'm happy.