I want to put 2 condition after the keyword AS in a procedure which are INVALID_BUDGET EXCEPTION and Event_ID varchar2(8) but this will cause error in oracle.
CREATE OR REPLACE PROCEDURE PRC_ADD_OVER_BUDGET_EVENT(V_EventType IN VARCHAR,V_EventBudget IN NUMBER,V_organizerID IN VARCHAR,v_FoodBeverage IN NUMBER,v_wine IN NUMBER ,v_Decoration IN NUMBER,v_rentalfee IN NUMBER,v_facility IN NUMBER)
AS INVALID_BUDGET EXCEPTION AND Event_ID varchar2(8);
PRAGMA exception_init(INVALID_BUDGET,-20000);
BEGIN
INSERT INTO Event values ( next_eventid_seq,v_eventType,v_eventbudget,null,null,null,v_organizerID) RETURNING EVENTid INTO event_ID;
INSERT INTO EventCost values (next_Costid_seq,v_FoodBeverage,v_Wine,v_Decoration,v_RentalFee,v_Facility,event_ID);
EXCEPTION WHEN INVALID_BUDGET THEN DBMS_OUTPUT.PUT_LINE(u'\000A' || 'Please enter budget of above 50000.');
End;
/
How to put the two condition in a procedure without any error.
Extra question: Can procedure handle two exception handler?
For multiple exception handling in oracle you can use this syntax. The exception-handling block contains series of WHEN condition to handle the exception.
BEGIN
<execution block>
.
.
EXCEPTION
WHEN <exceptionl_name>
THEN
<Exception handling code for the “exception 1 _name’' >
WHEN OTHERS
THEN
<Default exception handling code for all exceptions >
END;
Please refer the link
Variable definitions are separated by a semi-colon:
CREATE OR REPLACE PROCEDURE PRC_ADD_OVER_BUDGET_EVENT
(V_EventType IN VARCHAR,
V_EventBudget IN NUMBER,
V_organizerID IN VARCHAR,
v_FoodBeverage IN NUMBER,
v_wine IN NUMBER,
v_Decoration IN NUMBER,
v_rentalfee IN NUMBER,
v_facility IN NUMBER)
AS
INVALID_BUDGET EXCEPTION;
Event_ID varchar2(8);
PRAGMA exception_init(INVALID_BUDGET,-20000);
BEGIN
INSERT INTO Event
values (next_eventid_seq, v_eventType, v_eventbudget,
null, null, null, v_organizerID)
RETURNING EVENTid INTO event_ID;
INSERT INTO EventCost
values (next_Costid_seq, v_FoodBeverage, v_Wine, v_Decoration,
v_RentalFee, v_Facility, event_ID);
EXCEPTION
WHEN INVALID_BUDGET THEN
DBMS_OUTPUT.PUT_LINE(u'\000A' || 'Please enter budget of above 50000.');
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE(u'\000A' || 'Attempt to insert duplicate value ' ||
SQLERRM);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(u'\000A' || 'Something bad happened! ' || SQLERRM);
End;
And you can add as many exception handlers to your exception block as you want.
Best of luck.
Related
Using a procedure adds an employee record into the employee table, also validates the input values salary must be always greater than or equal to 500, raise a user-defined exception for any validation error.
You can create something like this. Add parameters for other columns as well
CREATE OR REPLACE PROCEDURE insert_emp (salary NUMBER)
AS
invalid_salary EXCEPTION;
BEGIN
IF salary < 500 THEN
RAISE invalid_salary;
ELSE
INSERT INTO employees(salary) VALUES (salary);
COMMIT;
END IF;
END;
You can also associate an Exception number with the exception
Exception number for user-defined exceptions must be in the range of -20000 to -20999
CREATE OR REPLACE PROCEDURE insert_emp (salary NUMBER)
AS
invalid_salary EXCEPTION;
PRAGMA EXCEPTION_INIT (invalid_salary, -20100);
BEGIN
IF salary < 500 THEN
RAISE invalid_salary;
ELSE
INSERT INTO employees(salary) VALUES (salary);
COMMIT;
END IF;
END;
This sounds like a homework problem so I'll let using a trigger go, except a possible gotta and th show a better way of handling it. You raise the user defined exception "invalid salary" however unless your code handles it Oracle will throw the error "ORA-06510 Unhandled user defined exception", indicating it does not know what with it. So what is a better way: Define the column and include a check constraint on it.
Create table employees (...
, salary number(8,2) not null
constraint salary_less_then_minimum check (salary >= 500)
, ...);
This is my Department table:
create table Department(
DeptNo int primary key,
DeptName varchar2(21) not null,
DeptLocation varchar2(13) not null
);
I am trying to insert value for DeptName column with length more than accepted i.e. 21, which means I should get "VALUE_ERROR" exception.
The plsql code I am running is:
begin
insert into department values(1, 'Some random department name', 'SomeLocation');
exception
when value_error then
dbms_output.put_line('Cannot store the value!');
end;
As I am trying to catch the exception, it is not getting caught. I am getting the error:
ORA-12899: value too large for column "SQL_ZIRHWMLFPCEAKPGYGJJZLSIFI"."DEPARTMENT"."DEPTNAME" (actual: 27, maximum: 21) ORA-06512: at line 2
ORA-06512: at "SYS.DBMS_SQL", line 1721
But if I change my exception from "value_error" to "others"
begin
insert into department values(1, 'Some random department name', 'SomeLocation');
exception
when others then
dbms_output.put_line('Cannot store the value!');
end;
then I get the expected output
Cannot store the value!
Where could I have gone wrong? Please let me know. Thanks!
PS: I am running all the code on livesql.oracle.com
Ideally, what you are using is correct and it should had worked as desired. But the exception VALUE_ERROR behaves differently in somecases. See the below illustrative example.
As per the documentation value_error comes when there is an
arithmetic, conversion, truncation, or size-constraint error occurs.
For example, when your program selects a column value into a character
variable, if the value is longer than the declared length of the
variable, PL/SQL aborts the assignment and raises VALUE_ERROR. In
procedural statements, VALUE_ERROR is raised if the conversion of a
character string into a number fails.
The last line says, In procedural statements, VALUE_ERROR is raised if the conversion of a character string into a number fails., but when i run this in a block it rasied INVALID_NUMBER exception.
SQL> declare
2 n number;
3 begin
4 select to_number('a')
5 into n
6 from dual
7 ;
8 exception
9 when value_error
10 then
11 dbms_output.put_line ('Value Error');
12 when invalid_number
13 then
14 dbms_output.put_line ('Invalid Number');
15 end;
16 /
Invalid Number
PL/SQL procedure successfully completed.
I expected that it would raise the VALUE_ERROR but it didn't. So it might be the case that Oracle was not able to raise value_error in your case and when you used WHEN OTHERS it was caught.
Edit:
Ok. So is it possible somehow to catch value_error exception by giving
the value longer than the declared length of the variable?
Explicit Raise of System Exception : Not very elegant but you can do it as below.
declare
var int;
var1 varchar2(21);
var2 varchar2(13);
begin
var1:='Some random department name';
var2:= 'SomeLocation'
If var1 > 21 then
RAISE VALUE_ERROR;
END IF;
If var2 > 13 then
RAISE VALUE_ERROR;
END IF;
insert into department values(1, var1, var2);
exception
when value_error then
dbms_output.put_line('Cannot store the value!');
end;
VALUE_ERROR was not the exception raised when you ran your code, if you want, you can defined an EXCEPTION and catch it, see below code for sample,
DECLARE
ORA_12899 EXCEPTION;
PRAGMA EXCEPTION_INIT(ORA_12899, -12899);
begin
insert into department values(1, 'Some random department name', 'SomeLocation');
exception
when ORA_12899 then
dbms_output.put_line('Cannot store the value!');
end;
/
Below code will have a VALUE_ERROR;
DECLARE
ORA_12899 EXCEPTION;
PRAGMA EXCEPTION_INIT(ORA_12899, -12899);
v_dept VARCHAR2(20);
begin
v_dept := 'Some random department name';
insert into department values(1, v_dept, 'SomeLocation');
exception
when ORA_12899 then
dbms_output.put_line('Cannot store the value!');
end;
/
when the following code is running exception statements are not rising automatically by the database server it's Happen when I enter wrong userid value or when the value is null , I don't want to use RAISE LOGIN_DENIED; explicitly in my code , so what do you think? am I missing something?
CREATE OR REPLACE PROCEDURE user_auth(
userid IN st_az.st_name%type ,
pass OUT st_az.st_pass%type ,
message OUT varchar2 ,
err_msg OUT varchar2 ) IS
BEGIN
message:= 'login is done successfully';
err_msg:= 'Login Denied .. Please Try Again!';
SELECT st_pass INTO pass FROM st_az WHERE st_name = userid ;
dbms_output.put_line(message);
EXCEPTION
WHEN LOGIN_DENIED THEN
dbms_output.put_line(err_msg);
END user_auth;
If you want to find info in st_az table and raise an error when there is no such row, you need NO_DATA_FOUND exception
CREATE OR REPLACE PROCEDURE user_auth(
userid IN st_az.st_name%type ,
pass OUT st_az.st_pass%type ,
message OUT varchar2 ,
err_msg OUT varchar2 ) IS
BEGIN
message:= 'login is done successfully';
err_msg:= 'Login Denied .. Please Try Again!';
SELECT st_pass INTO pass FROM st_az WHERE st_name = userid ;
dbms_output.put_line(message);
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line(err_msg);
END user_auth;
Your original code of the question needs some modification. The actual parameter that corresponds to an OUT formal parameter must be a variable; it cannot be a constant or an expression.
Now, if you don't want to use LOGIN_DENIED then you can either try using NO_DATA_FOUND or simple generalized OTHERS in exception block.
The code may be like this--
CREATE OR REPLACE
PROCEDURE user_auth(
userid IN st_az.st_name%type ,
pass OUT st_az.st_pass%type ,
MESSAGE OUT VARCHAR2 ,
err_msg OUT VARCHAR2 )
AS
message1 VARCHAR2(50);
err_message1 VARCHAR2(50);
BEGIN
message1 := 'login is done successfully';
err_message1:= 'Login Denied .. Please Try Again!';
SELECT st_pass INTO pass FROM st_az WHERE st_name = userid ;
MESSAGE:= message1;
dbms_output.put_line(MESSAGE);
EXCEPTION
WHEN OTHERS THEN
err_msg:= err_message1;
dbms_output.put_line(err_msg);
END user_auth;
Now testing above code:--
create table st_az(st_name varchar2(10),st_pass varchar2(10));
insert into st_az values ('aa','aa');
insert into st_az values ('bb','bb');
commit;
Creating anonymous block and call procedure:-
DECLARE
MESSAGE VARCHAR2(50);
err_msg VARCHAR2(50);
pass VARCHAR2(10);
BEGIN
user_auth('cc',pass,MESSAGE,err_msg);
END;
I am using the following code for stopping null value insert into table using trigger. But when I pass null value, the inserting is happening fine. Any idea what am I doing wrong here?
create table test
(col1 number,
col2 varchar2(40)
)
create or replace trigger test_trg
after insert on test
for each row
declare
excp exception;
pragma autonomous_transaction;
begin
if :new.col2 is null then
RAISE excp;
end if;
exception
when excp then
dbms_output.put_line('error');
rollback;
end;
(Please note, I do accept that using a not null or a check constraint on the col2 is a better solution. I just want to find out the reason behind the error in this seemingly correct code)
Don't rollback in trigger, just re-raise excpetion after logging it:
create or replace trigger test_trg
after insert on test
for each row
declare
excp exception;
pragma autonomous_transaction;
begin
if :new.col2 is null then
RAISE excp;
end if;
exception
when excp then
dbms_output.put_line('error');
raise; -- propagate error
end;
When you put "exception ... end;" block in code you say to PL/SQL that managing consequences of this error is on your responsibility. So, if you don't raise any error from a code which handles original error, for PL/SQL it means that all actions regarding this error already done in your code, all went OK and record must be inserted.
You can try it in this SQLFiddle.
you have to define the trigger as BEFORE INSERT to fire before the insert is executed, remove the pragma autonomouse_transaction and the rollback (they have no sense here, because you do not any DML), then reraise the exception in the exception handler
I need to handle the ORA-01400 error (cannot insert NULL into ("SCHEMA"."TABLE_NAME"."COLUMN_NAME") ) using a exception handle.
ORACLE Predefine a few Exceptions like (ACCESS_INTO_NULL, ZERO_DIVIDE and so on), but apparently does not define an Exception for the ORA-01400 error, how do I handle this particular error code?
I need something like this (other suggestions are accepted).
....
...
INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);
COMMIT;
EXCEPTION
WHEN NULL_VALUES THEN /* i don't know this value , exist?*/
Do_MyStuff();
WHEN OTHERS THEN
raise_application_error(SQLCODE,MY_OWN_FORMAT_EXCEPTION(SQLCODE,SQLERRM),TRUE);
END;
The pre-defined PL/SQL exceptions are special to Oracle. You really can't mess with those. When you want to have a set of predefined exceptions of your own you can't declare them "globally" like the standard ones. Instead, create an exceptions package which has all of the exception declarations and use that in your application code.
Example:
CREATE OR REPLACE PACKAGE my_exceptions
AS
insert_null_into_notnull EXCEPTION;
PRAGMA EXCEPTION_INIT(insert_null_into_notnull, -1400);
update_null_to_notnull EXCEPTION;
PRAGMA EXCEPTION_INIT(update_null_to_notnull, -1407);
END my_exceptions;
/
Now use the exception defined in the package
CREATE OR REPLACE PROCEDURE use_an_exception AS
BEGIN
-- application specific code ...
NULL;
EXCEPTION
WHEN my_exceptions.insert_null_into_notnull THEN
-- application specific handling for ORA-01400: cannot insert NULL into (%s)
RAISE;
END;
/
Source: http://www.orafaq.com/wiki/Exception
you can define your own exceptions, like variables (they will have the same scope as other variables so you can define package exception, etc...):
SQL> DECLARE
2 NULL_VALUES EXCEPTION;
3 PRAGMA EXCEPTION_INIT(NULL_VALUES, -1400);
4 BEGIN
5 INSERT INTO t VALUES (NULL);
6 EXCEPTION
7 WHEN null_values THEN
8 dbms_output.put_line('null value not authorized');
9 END;
10 /
null value not authorized
PL/SQL procedure successfully completed
You can handle exception by its code like this:
....
...
INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -1400 THEN
Do_MyStuff();
ELSE
raise_application_error(SQLCODE,MY_OWN_FORMAT_EXCEPTION(SQLCODE,SQLERRM),TRUE);
END IF;
END;
INSERT INTO MY_TABLE (CODE, NAME) VALUES (aCode,aName);
COMMIT;
EXCEPTION
WHEN NULL_VALUES /* i don't know this value , exist?*/
emesg := SQLERRM;
dbms_output.put_line(emesg);
WHEN OTHERS THEN
emesg := SQLERRM;
dbms_output.put_line(emesg);
END;
SQLERRM shows the sql error message
http://www.psoug.org/reference/exception_handling.html