Oracle exception information - oracle

I'm wondering if there is a way to get a little more information about what caused the exception:
Error starting at line 5 in command:
exec ....
Error report:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at ..., line 558
ORA-06512: at ..., line 752
ORA-06512: at line 1
06502. 00000 - "PL/SQL: numeric or value error%s"
*Cause:
*Action:
I'm assuming this means I have a variable that is too small for what I tried to put in it... But why can't Oracle tell me what variable this is? It would be great for both debugging and production support people to be able to say to our client I think you have this field too big and that's what caused the error, rather than just "some value was too big and we really have no idea which one"... Using the line number would required someone who understood sql and looking at the code which is not ideal.
Why is there nothing under the Cause and Action fields?
When you try to insert into a col with data that is too large it tells you what col... I would like similar information here.
Is that possible without having to put an exception handler after every plsql line of code?

Oracle can't know what your intent is with the error information. Knowing the variable name you're storing it as or where exactly it came from isn't necessarily in the best interests of the end user or security.
For example, I can generate your error easily:
SQL> declare
2 v_tooshort varchar2(3);
3 begin
4 select 'too long' into v_tooshort from dual;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
The error already gives the line number.
Would you prefer the error give the variable name (v_tooshort)? That's not helpful to a user.
Is the right information the value, "too long"? Or the fact that it's a dummy column from the dual table? (or an actual column and table)?
Because the error arises from a select into instead of an insert statement, it's not like there's a specific database constraint the exception can identify by name.
EDIT (to address issue raised in a comment):
That's not true. You'll get the column name and lengths returned when doing an insert (as an ORA-12899), but not when doing a select into even if it's using data from a table:
SQL> create table test_length (tooshort varchar2(3));
Table created.
SQL> begin
2 insert into test_length(tooshort) values ('too long');
3 end;
4 /
begin
*
ERROR at line 1:
ORA-12899: value too large for column "MYUSER"."TEST_LENGTH"."TOOSHORT"
(actual: 8, maximum: 3)
ORA-06512: at line 2
SQL> insert into test_length(tooshort) values ('abc');
1 row created.
SQL> commit;
Commit complete.
SQL> declare
2 v_onechar varchar2(1);
3 begin
4 select tooshort into v_onechar from test_length;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error: character string buffer too small
ORA-06512: at line 4
EDIT 2:
You can nest your select into into its own begin-exception-end block and raise whatever error you like (providing a unique error number and descriptive error text):
SQL> ed
Wrote file afiedt.buf
1 declare
2 v_onechar varchar2(1);
3 begin
4 select tooshort into v_onechar from test_length;
5 exception
6 when value_error then
7 RAISE_APPLICATION_ERROR(-20011, 'my variable named v_onechar is too short for the data returned from test_lengt
h.tooshort');
8* end;
SQL> /
declare
*
ERROR at line 1:
ORA-20011: my variable named v_onechar is too short for the data returned from
test_length.tooshort
ORA-06512: at line 7

Related

Is no-data-found exception not raised implicitly?

question 1:
I noticed the no-data-found exception not raised implicitly, do we need to raise them manually/explicitly?
Question 2:
I writing a SP package with 4 procedures in it and i'm writing below procedures on a single table.
the exception handling is repetitive in each procedure. is there any guidance/coding standard to keep it in a single place procedure#5 or function and call it there.
Select
Update
Insert
Delete
I guess if I keep it in a function it would raise the exception and return to the called procedure and continue to run ? but when we raise a exception the program should stop , right?
You have run into the only exception in PL/SQL exception handling - ORA-1403: no data found is suppressed when it is generated by a function called in a SQL context.
No data found exceptions work fine in PL/SQL anonymous blocks:
SQL> declare
2 v_number number;
3 begin
4 select 1 into v_number from dual where 1=0;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at line 4
And no data found also works as expected with a function called in a PL/SQL statement:
SQL> create or replace function exception_no_data_found return number is
2 v_number number;
3 begin
4 select 1 into v_number from dual where 1=0;
5 return v_number;
6 end;
7 /
Function created.
SQL> declare
2 v_number number;
3 begin
4 v_number := exception_no_data_found;
5 end;
6 /
declare
*
ERROR at line 1:
ORA-01403: no data found
ORA-06512: at "JHELLER.EXCEPTION_NO_DATA_FOUND", line 4
ORA-06512: at line 4
But when calling the function in a SQL context, the exception disappears:
SQL> select exception_no_data_found from dual;
EXCEPTION_NO_DATA_FOUND
-----------------------
I think the reason for this is that SQL internally uses the no data found exception to let the system know there are no more rows, so it's not always an exception. (This behavior is probably a bug but has been around for so long that it'll never change.)
To raise that exception in this situation, you must manually catch and raise a different exception like this:
SQL> create or replace function exception_no_data_found return number is
2 v_number number;
3 begin
4 select 1 into v_number from dual where 1=0;
5 return v_number;
6 exception when no_data_found then
7 raise_application_error(-20000, 'No data found.');
8 end;
9 /
Function created.
SQL> select exception_no_data_found from dual;
select exception_no_data_found from dual
*
ERROR at line 1:
ORA-20000: No data found.
ORA-06512: at "JHELLER.EXCEPTION_NO_DATA_FOUND", line 7
But the above situation is by far the weirdest part about Oracle exception handling. Other than this scenario, in general you are almost always better off by not doing any exception handling. Just let the program break; the exceptions will propagate up, and the application will get an exception that includes the full error message and the exact line number of the error. In practice, that information is almost always enough to debug any problems. Only add custom exception handling when you know for sure that you need to gather extra data.

How to avoid this in PLSQL

I'm trying to create a function that looks like this
CREATE OR REPLACE FUNCTION get_sal
(dep_id IN departments.department_id%TYPE)
RETURN NUMBER IS
v_sal employees.salary%TYPE;
BEGIN
SELECT AVG(salary) INTO v_sal FROM Employees
WHERE department_id = dep_id;
RETURN v_sal;
END;
And I get an error that says
Error starting at line : 5 in command -
BEGIN
SELECT AVG(salary) INTO v_sal FROM Employees
WHERE department_id = dep_id;
RETURN v_sal;
END;
Error report -
ORA-06550: line 3, column 27:
PL/SQL: ORA-00904: "DEP_ID": invalid identifier
ORA-06550: line 2, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 4, column 5:
PLS-00372: In a procedure, RETURN statement cannot contain an expression
ORA-06550: line 4, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I got an example function from Oracle to see if it works but the same error appears.
There's nothing wrong with the function:
SQL> CREATE OR REPLACE FUNCTION get_sal (dep_id IN departments.department_id%TYPE)
2 RETURN NUMBER
3 IS
4 v_sal employees.salary%TYPE;
5 BEGIN
6 SELECT AVG (salary)
7 INTO v_sal
8 FROM Employees
9 WHERE department_id = dep_id;
10
11 RETURN v_sal;
12 END;
13 /
Function created.
SQL> select get_sal(10) from dual;
GET_SAL(10)
-----------
SQL>
as long as schema you're connected to contains DEPARTMENTS and EMPLOYEES tables with columns mentioned in that code. If you do not, then yes - expect errors.
As it seems you are using Sql Developer 20.4.0 as your SQL client, i guess the problem comes from the way you're compiling your SQL statement within this SQL client.
With SQL Developer, there is two ways to compile a SQL statement/execute a query. Selecting it in the editor and then click the green play button on the left as shown in the image below. The second way is to have only your statements in the editor and use the execute script button which is the second button to the right of the green play button. This one will execute all the statements in the editor.
I guess your error come from the use of the green play button while your cursor in the editor is on the statement but the statement is not fully selected or partially selected.
You can make SQL Developer complies with the behavior of Toad or have a custom behavior in this way in the SQL Developer options.

Write a PL/SQL procedure with no parameters Ins_Job that inserts new record in table JOBS

CREATE OR REPLACE PROCEDURE Insert_Job AS
v_job_id VARCHAR2(10) := 'HR_Assistant';
v_job_title VARCHAR2(35) := 'HRessourcesAssistant';
v_Min_Salary NUMBER(22):= 400;
v_max_salary NUMBER (22):= 5000;
BEGIN
INSERT INTO OEHR_JOBS (JOB_ID, JOB_TITLE,MIN_SALARY,MAX_SALARY)
VALUES (v_job_id, v_job_title, v_Min_Salary, v_max_salary);
dbms_output.put_line('Insertion OK');
End;
Write a PL/SQL procedure with no parameters Insert_Job that inserts a new record in the table JOBS: - Job Id: Assistant - Job title: HRessources Assistant - Min Salary: 400 - Max Salary: 5000 The procedure should print a message to the user to inform him about the insertion status (success/ Error). Call the procedure and take a screenshot of the output in both cases.
This is what I try and it doesn't work any help please? It created the procedure but no data into the table, an also when I call it it shows me an error. I'm usnig APEX ORACLE HERE IS THE ERROR MESSAGE BELOW
ORA-06550: line 2, column 1:
PLS-00905: object WKSP_ELIASHOME.INSERT_JOB is invalid
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_200200", line 626
ORA-06550: line 2, column 1:
PL/SQL: Statement ignored
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1658
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_200200", line 612
ORA-06512: at "APEX_200200.WWV_FLOW_DYNAMIC_EXEC", line 1749
When I read your error message: numeric or value error: character string buffer too small
This mean your length is too small.
In your code:
v_job_id VARCHAR2(10) := 'HR_Assistant';
It was because length 'HR_Assistant' is longer then 10
Try to change lenght v_job_id into:
v_job_id VARCHAR2(12) := 'HR_Assistant';
Or you can remove some character, into:
v_job_id VARCHAR2(10) := 'Assistant';
Or, maybe you must check first length from column JOB_ID in table OEHR_JOBS
Sorry if my english bad and I don't really familiar with PLSQL.

PL SQL Stored Procedure for new Transaction and order

I'm giving a small snippet of my code but I 'm receiving the below error when trying to create a new order for a stored Oracle pl sql procedure.
line 83 is the insert statement in the code and line 84 is in the insert part of the statement.
83/5 PL/SQL: SQL Statement ignored
84/47 PL/SQL: ORA-00984: column not allowed here
BEGIN
--Initializing values for variables
x_rowcount := 0;
x_stockonhand := 0;
Totaldue := 0;
--Total due calculation
--(price of phone*quantity + shipping cost)*1.06 (assuming 6% sales tax)
Totaldue := (((i_price * c_p_qty) + i_shipping_cost) * 1.06);
SAVEPOINT start_transaction; -- mark a savepoint
--INSERT a new record into order table.
INSERT INTO orders(o_id,c_id,p_id,s_id,order_date,o_qty,order_total,card_type,cc_number,exp_date,shipping_status)
VALUES (orders_seq.nextval, c_c_id,c_p_id,s_id,sysdate,c_p_qty,Totaldue,c_card_type,c_cc_number,c_exp_date,'Not shipped yet');
Check your declaration section. Usually this error appears when you make a typo in variable name or variable not declared. For example:
SQL> create table tmp (id number, str varchar2(100));
Table created.
SQL> declare
a number;
begin
insert into tmp (id, str)
values (a, a1);
end;
/
values (a, a1);
*
ERROR at line 5:
ORA-06550: line 5, column 14:
PL/SQL: ORA-00984: column not allowed here
ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
The error is because one or more of the values in your VALUES(...,...) section is invalid.
I would suggest checking each one to see that they are valid. For example, is c_c_id declared and given a value somewhere else in the code? If not, this is likely your problem. Each one needs to be declared and given a value before it can be put in the VALUES(...,...) section of the INSERT statement.
INSERT INTO orders(o_id,c_id,p_id,s_id,order_date,o_qty,order_total,card_type,cc_number,exp_date,shipping_status)
VALUES (orders_seq.nextval, c_c_id,c_p_id,s_id,sysdate,c_p_qty,Totaldue,c_card_type,c_cc_number,c_exp_date,'Not shipped yet');

PL/SQL : i have a function but there is an error : "in a procedure,RETURN can not contain an expression"

Here is my code:
CREATE OR REPLACE FUNCTION customer_city_function(city_in IN VARCHAR2)
RETURN NUMBER
AS
number_cus NUMBER := 0;
CURSOR cus_cur IS
SELECT COUNT(*)
FROM customer
WHERE customer_city = city_in;
BEGIN
IF city_in IS NOT NULL THEN
OPEN cus_cur;
FETCH cus_cur INTO number_cus;
CLOSE cus_cur;
END IF;
RETURN number_cus;
END;
/
and here is warnings:
Error starting at line : 1 in command -
CREATE OR REPLACE FUNCTION customer_city_function(city_in IN VARCHAR2)
RETURN NUMBER
AS
number_cus NUMBER := 0
Error report -
SQL Command: functıon CUSTOMER_CITY_FUNCTION
Failed: Warning: executing is completed with a warning
Error starting at line : 5 in command -
CURSOR cur_cur IS
Error report -
Unknown Command
Error starting at line : 6 in command -
SELECT COUNT(*)
FROM costumer
WHERE customer_city=city_in
Error at Command Line : 8 Column : 25
Error report -
SQL Error: ORA-00904: "CITY_IN": undefined variable
00904. 00000 - "%s: invalid identifier"
*Cause:
*Action:
Error starting at line : 9 in command -
BEGIN
IF city_in IS NOT NULL
THEN
OPEN cus_cur;
FETCH cus_cur INTO number_cus;
CLOSE cus_cur;
END IF;
RETURN (number_cus);
END;
Error report -
ORA-06550: row 2, column 6:
PLS-00201: 'CITY_IN' variable should been defined
ORA-06550: row 2, column 3:
PL/SQL: Statement ignored
ORA-06550: row 8, column 1:
PLS-00372: in a procedure, RETURN can not contain an expression
ORA-06550: row 8, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Where is my mistake? I can't find it, it doesn't make any sense.
(I translated this warning message from my language. I hope I did it right.)
I have just tried it in Command Window and it works. Why doensn't it work in Oracle SQL Developer sql worksheet?
There is nothing wrong with your posted code. The issue might be with your client or the way you are compiling the code.
As you have mentioned PL/SQL Developer in the tags, it might be possible that you have some extra characters in the SQL Worksheet and you are compiling the function as a script, thus the compiler finds it erroneous.
Here is a demo in SQL*Plus, and there is no error:
SQL> CREATE OR REPLACE FUNCTION customer_city_function(i_deptno IN number)
2 RETURN NUMBER
3 AS
4 number_cus NUMBER := 0;
5 CURSOR cus_cur IS
6 SELECT COUNT(*)
7 FROM emp
8 WHERE deptno=i_deptno;
9 BEGIN
10 IF i_deptno IS NOT NULL
11 THEN
12 OPEN cus_cur;
13 FETCH cus_cur INTO number_cus;
14 CLOSE cus_cur;
15 END IF;
16 RETURN number_cus;
17 END;
18 /
Function created.
SQL> sho err
No errors.
SQL> SELECT customer_city_function(10) FROM DUAL;
CUSTOMER_CITY_FUNCTION(10)
--------------------------
3
SQL>
The only difference in my code is that I have used EMP table instead of CUSTOMERS table and the input parameter is DEPTNO instead of CITY_IN. Rest everything is same and function compiles and executes without any errors.

Resources