Clob functions doesn't work in Oracle 19.3.0.0 - oracle

I have been trying to use different functions on clob datatype in oracle 19.3.0.0 and none of them return values.
eg : -
dbms_lob.getlength(clob_data)
However any kind of functions on clob/blob datatype doesn't return values
length(clob_data)
These functions have been working fine previously in Oracle 12c. I recently upgraded to Oracle 19.3.0.0. Please educate me if there is any work around for this.

If you don't want to insert anything in clob column you should use empty_clob function
Test case
SQL> create table test1 (id number,a clob);
Table created.
SQL> insert into test1 values (&id,&a);
Enter value for id: 1
Enter value for a: null
1 row created.
SQL> /
Enter value for id: 2
Enter value for a: empty_clob()
1 row created.
SQL> commit;
Commit complete.
SQL> select id,dbms_lob.getlength(a) length from test1;
ID LENGTH
---------- ----------
1
2 0

Related

the tables i have created in sqlplus not appearing in Navicat lite

Guys I am using oracle 11g and I am pretty new with it.
the problem is when I try to create a table and insert a value in sqlplus terminal, it is not showing in the Navicat lite(Graphical representation software).
Here, let me make this more clear by showing you the pictures.
here are the rows that are getting printed on SQLPlus terminal
But take a look at the rows in the Navicat
Here the table name is TIME.
Can anyone explain to me what is the problem?
Looks like you didn't
commit;
in SQL*Plus after inserting rows. Unless you do that, those values are visible only to you, but not other sessions (which is what Navicat sees). So - commit.
As of letter case and double quotes:
This is how you should be doing it - don't use double quotes, reference tables any way you want:
SQL> create table test (id number);
Table created.
SQL> insert into test (id) values (1);
1 row created.
SQL> select * from test;
ID
----------
1
SQL> select * from TEST;
ID
----------
1
SQL> select * from tEsT;
ID
----------
1
SQL> drop table test;
Table dropped.
If you use double quotes, you have to reference the table exactly the same way as you created it:
SQL> create table "test" (id number);
Table created.
SQL> insert into test (id) values (1);
insert into test (id) values (1)
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> insert into TEST (id) values (1);
insert into TEST (id) values (1)
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> insert into "TEST" (id) values (1);
insert into "TEST" (id) values (1)
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> insert into "test" (id) values (1);
1 row created.
SQL>

SQL developer: How to make log output from a trigger?

I've made a trigger in SQL and need him to write an output after inserting a new row in the table. Please see the example:
CREATE OR REPLACE TRIGGER GAS_CODES AFTER
INSERT ON blablatable
FOR EACH ROW
BEGIN
insert into blabla2table (...,...,...,...)
values (:new...,...,...,..);
---output:
dbms_output.put_line('New row has been added.');
END;
/
When I compile the trigger, it shows in the Script Output, but if I add a new row into the table, there's nothing.
You are missing SET SERVEROUTPUT ON. This command is understandable also by SQLDeveloper.
Let's do a quick test inside the SQLDeveloper.
CREATE USER "TEST_SCHEMA" IDENTIFIED BY "TEST";
User "TEST_SCHEMA" created.
GRANT UNLIMITED TABLESPACE TO "TEST_SCHEMA";
Grant succeeded.
CREATE TABLE "TEST_SCHEMA"."NAMES" ("ID" NUMBER, "NAME" VARCHAR2(25), PRIMARY KEY("ID"));
Table "TEST_SCHEMA"."NAMES" created.
CREATE OR REPLACE TRIGGER "TEST_SCHEMA"."NAMES_TRG_1" AFTER
INSERT ON "TEST_SCHEMA"."NAMES"
FOR EACH ROW
BEGIN
DBMS_OUTPUT.PUT_LINE('New row has been added.');
END;
/
Trigger NAMES_TRG_1 compiled
SET SERVEROUTPUT ON
This command won't print anything in SQL Developer. No worries here.
INSERT INTO "TEST_SCHEMA"."NAMES" VALUES (1, 'Mark Smith');
1 row inserted.
New row has been added.
As you can see, the output was there and it was inserted after the actual row was inserted into the table. Works fine.
To cleanup the testcase, run this:
DROP USER "TEST_SCHEMA" CASCADE;
EDIT 1:
When you are working with Table Data Editor, this is behaving differently. Table Data Editor has its own Oracle session and it has different way of capturing DBMS Output.
To open the DBMS capture window, you need to click on "VIEW" menu and select "DBMS Output" option.
Then click the green plus button and set the database, that will be captured.
Now you can see the output.
Beware as the output here is not "realtime", this window will show something only when there is a buffer flush, and the buffer flush cannot be invoked manually/directly.
Most likely the client (SQLDeveloper) doesn't read the output buffer.
To enable this you must choose from menu "view" -> "dbms output" and then click the green "+" in the dbms output window to read the output buffer for your connection ...
In sqlplus you can do it like this:
SQL> drop table tst purge;
Table dropped.
SQL> drop table tst2 purge;
Table dropped.
SQL> create table tst ( tst_no integer);
Table created.
SQL> create table tst2 ( tst_no integer);
Table created.
SQL> create or replace trigger tst_trg after insert on tst
for each row
begin
insert into tst2 (tst_no) values (:new.tst_no);
dbms_output.put_line('new row with tst_no='|| :new.tst_no);
end;
/ 2 3 4 5 6 7
Trigger created.
SQL> set serveroutput on;
exec dbms_output.enable;
insert into tst values (1); SQL>
PL/SQL procedure successfully completed.
SQL> SQL>
new row with tst_no=1
1 row created.
SQL> r
1* insert into tst values (1)
new row with tst_no=1
1 row created.
SQL> select * from tst2;
TST_NO
----------
1
1
SQL>
as you can see the output is read and printed in sqlplus, and rows are inserted into the target table tst2
hope it helps...

Oracle "Number" datatype precision

We are trying to store the values in a table which has a column of "Number" Datatype. The problem arises when we store a very small value , like "0.000001.
SQL> desc testing
Name Type Nullable Default Comments
---- ------ -------- ------- --------
A NUMBER Y
SQL> insert into testing values (0.00000001);
1 row inserted
SQL> select * from testing;
A
----------
0.001
1E-5
1E-8
0.0001
Is there a way, we can store and retrieve the absolute values, as in store, 0.00001 instead of 1E-5.
It is simply a DISPLAY issue. Set numformat properly.
For example,
SQL> create table t(a number);
Table created.
SQL> insert into t values(0.000000000000001);
1 row created.
SQL> select * from t;
A
----------
1.0000E-15
SQL> set numformat 9D9999999999999999
SQL> select * from t;
A
-------------------
.0000000000000010
SQL>
Update OP says the above didn't fix the issue when trying to send the number value to the application frontend. There must be something wrong with the locale-specific NLS settings that is being used by the application.
If the issue is with just the display, then you could convert it to char using to_char and proper format model.
SQL> create table t(a number);
Table created.
SQL> insert into t values(.000000000000000000001);
1 row created.
SQL> select * from t;
A
----------
1.0000E-21
SQL> select ltrim(to_char(a, '9999999D999999999999999999999', 'NLS_NUMERIC_CHARACTERS = ''.,''')) num from t
NUM
------------------------------
.000000000000000000001
SQL>
Note the use of ltrim.

Concatenate String with a column in trigger

I have a table called TBL_CAS. In that, FLD_ID as auto increment column and another column is called FLD_CAS_CODE. Now I need to add CAS- as a prefix to FLD_ID and Insert into FLD_CAS_CODE. I need to do this in trigger. I was tried with the below code, But the data in not inserting, What is the problem ?
CREATE OR REPLACE TRIGGER TBL_CAS_TRG
BEFORE INSERT ON TBL_CAS
FOR EACH ROW
BEGIN
:NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
END;
I mean `"cas-"+"fld_id"="cas-fld_id"'
You don't need to put TO_CHAR() around things which are already charcater datatypes. But you should cast the numeric identifier (rather than relying on implicit conversion):
:NEW.FLD_CAS_CODE := 'CAS-'||TRIM(TO_CHAR (:NEW.FLD_ID));
which part isn't working exactly? as your trigger seem to work just fine.
SQL> create table TBL_CAS( FLD_ID number, FLD_CAS_CODE varchar2(20));
Table created.
SQL> CREATE OR REPLACE TRIGGER TBL_CAS_TRG
2 BEFORE INSERT ON TBL_CAS
3 FOR EACH ROW
4 BEGIN
5 :NEW.FLD_CAS_CODE := TO_CHAR ('CAS')||'-'||:NEW.FLD_ID;
6 END;
7 /
Trigger created.
SQL> insert into TBL_CAS (fld_id) values (1001);
1 row created.
SQL> select * From TBL_CAS;
FLD_ID FLD_CAS_CODE
---------- --------------------
1001 CAS-1001
SQL>
This will also work fine:
CREATE OR REPLACE TRIGGER TBL_AREA_CODES_TRG
BEFORE INSERT ON TBL_AREA_CODES
FOR EACH ROW
BEGIN
:NEW.OBRM_AREA_CODE := :NEW.STATE_CODE ||'-'||:NEW.DIST_CODE ||'-'||:NEW.CITY_CODE ||'-'||:NEW.AREA_CODE ;
END;

Inconsistent datatypes in Oracle

i have the following function:
create or replace
FUNCTION "MXUPGKEYVAL"(tbname varchar2,colname varchar2) return number is
val number;
BEGIN
EXECUTE IMMEDIATE
'select sum(length('||colname||')) from '||tbname into val;
return val;
END;
and the following update:
update ANINTEGDATA set val1=to_char(nvl(MXUPGKEYVAL(MX5T,MX5C),0)) where type=1;
when i execute the update i get:
ORA-00932: inconsistent datatypes: expected NUMBER got LONG
ORA-06512: at "MAXIMO.MXUPGKEYVAL", line 6
ORA-06512: at line 2
any idea why that happens?
Regards,
Radu.
Later edit:
table ANINTEGDATA is:
create table ANINTEGDATA
(
MX5T VARCHAR2(50),
MX5C VARCHAR2(50),
MX6T VARCHAR2(50),
MX6C VARCHAR2(50),
TYPE NUMBER,
VAL1 VARCHAR2(200),
VAL2 VARCHAR2(200)
);
Your function works.
SQL> select mxupgkeyval('EMP', 'SAL') from dual
2 /
MXUPGKEYVAL('EMP','SAL')
------------------------
78
SQL>
Furthermore it works in your update statement.
SQL> update ANINTEGDATA set val1=to_char(nvl(MXUPGKEYVAL(MX5T,MX5C),0)) where type=1;
1 row updated.
SQL>
Where it doesn't work is when the column in question has the LONG datatype. The error message isn't as clear as it could be but is clear enough.
SQL> alter table t34 add long_col long;
Table altered.
SQL> select mxupgkeyval('T34', 'LONG_COL') from dual
2 /
select mxupgkeyval('T34', 'LONG_COL') from dual
*
ERROR at line 1:
ORA-00932: inconsistent datatypes: expected NUMBER got LONG
ORA-06512: at "APC.MXUPGKEYVAL", line 6
SQL>
This is just another reason why LONG is Teh Suck! and should have been done away with a long time ago. As you're doing a data migration exercise now would be a good time to consider moving to the oh-so flexible CLOB data type.
Either way you need a convention to indicate that the target column contains a shedload of data.
If you really need to know the precise extent of the LONG data volumes I suggest you unload the LONGs to CLOB columns and sum those instead.

Resources