I have the following trigger created:
create or replace TRIGGER MY_TRIGGER
BEFORE UPDATE OF PRODUCT_ID ON MY_TABLE
FOR EACH ROW
DECLARE
V_COUNT NUMBER;
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
SELECT DISTINCT PRODUCT_NAME
INTO :NEW.PRODUCT_NAME
FROM ALL_PRODUCTS_TABLE
WHERE PRODUCT_ID = :NEW.PRODUCT_ID;
EXCEPTION
WHEN no_data_found THEN
:NEW.PRODUCT_NAME := 'Not found';
END;
The code runs correctly when updating if the exception is removed (except when, there's no value, evidently). However, if I add the exception and test the trigger by using an existing/valid Product ID, it will return 'Not Found' regardless of what product id was used.
Not sure why or what am I missing.
Thanks
Related
I am getting no data found error in pl/sql
Actually problem is in the trigger
I want to use NO_DATA_FOUND error in the elsif statement
alter table SUPPLIER add trusted_supplier VARCHAR(30)
and then update it with the data that I load in the table
UPDATE SUPPLIER SET trusted_supplier ='Exotic Liquids'
while using the select statement I have only one value in the trusted_supplier so if insert value in the product is not equal to that
trusted supplier value I am getting error as no data found
is there any way i use NO_DATA_FOUND error which is predefined in pl/sql in the else if statement
CREATE OR REPLACE TRIGGER CHECK_SUPPLIER
BEFORE INSERT ON PRODUCT
FOR EACH ROW
DECLARE
supplier_info varchar(400);
except1 exception;
begin
select SUPPLIER_NAME
INTO supplier_info
FROM PRODUCT P JOIN SUPPLIER S
ON S.COMPANY_NAME = P.SUPPLIER_NAME
where S.trusted_supplier = :NEW.SUPPLIER_NAME ; here
if(supplier_info = 'Exotic Liquids') then
dbms_output.put_line('trusted supplier')
elsif
---------here
END IF;
exception
when except1 then
dbms_output.put_line('its not the trusted supplier');
END;
/
Create a PL/SQL Procedure to insert employee details into Employee table. Before inserting, check whether the employee age is eligible or not. Employee age should be 18 or greater. Values are passed as argument to the procedure.
If age valid, insert employee record into table and print the message "Age valid - Record inserted", else print the message "Age invalid - Record not inserted" by raising an exception.
coding:
CREATE OR REPLACE PROCEDURE CHECK_AGE_ELIGIBILITY(
v_id IN EMPLOYEE.EMPID%TYPE,
v_name IN EMPLOYEE.EMPNAME%TYPE,
v_age IN EMPLOYEE.AGE%TYPE)AS
BEGIN
INSERT INTO Employee(EMPID,EMPNAME,AGE)Values(103,'Robert',24);
select age from Employee;
IF AGE >=18
dbms_output.put_line('Age valid -Record inserted');
else
dbms_output.put_line('Age invalid -Record not inserted');
END;
/
EXPECTED OUTPUT:
Age valid -Record inserted
You want to check first, then insert if the check succeds (while your code is doing things the other way around). I also fixed the syntax of your if statement, and changed the insert statement so it uses the procedure arguments instead of hardcoded values. Finally, if you want to raise an error, then use raison_application_error() rather than put_line().
This should do what you want:
create or replace procedure check_age_eligibility(
v_id in employee.empid%type,
v_name in employee.empname%type,
v_age in employee.age%type
)
as
begin
if v_age >=18 then
insert into employee(empid,empname,age)values(v_id, v_name, v_age);
dbms_output.put_line('age valid -record inserted');
else
raise_application_error( -20001, 'age invalid - record not inserted' );
end if;
end;
/
Although this might not be what you were asked to do, please note that you don't need a procedure for this. You can just use a check constraint:
alter table employee add constraint age_above_18 check(age >= 18);
You can then use regular insert statements to feed the table - an error is raised for each row that conflicts with the constraint.
Demo on DB Fiddle
If you want to include the user-defined exception. declare it inside the procedure.
create or replace PROCEDURE CHECK_AGE_ELIGIBILITY(
v_id IN EMPLOYEE.EMPID%TYPE,
v_name IN EMPLOYEE.EMPNAME%TYPE,
v_age IN EMPLOYEE.AGE%TYPE) as
not_of_age exception;
begin
if v_age>=18 then
insert into EMPLOYEE(empid,empname,age) values(v_age,v_name,v_age);
dbms_output.put_line('Age valid - Record inserted');
else
raise not_of_age;
end if;
exception
when not_of_age then
dbms_output.put_line('Age invalid - Record not inserted');
end;
/
Just having a problem with ensuring a constraint is not violated.
Goal: To insert a record that does not violate a constraint.
Constraint: An order should not be allowed if it is discontinued or out of stock.
Now I have a procedure that I was working on and have the necessary syntax working. Just need the finishing touches to get this insert procedure working.
/* Creating Procedure */
CREATE PROCEDURE INSERT_ORDER_DETAIL(
--PARAMETERS
p_product_name IN VARCHAR,
p_unit_price IN NUMBER,
p_quantity IN NUMBER,
p_discount IN NUMBER) IS
--VARIABLES AND DECLARATION FOR PROCEDURE
p_order_id NUMBER;
PRODUCT_LIST PRODUCT%ROWTYPE;
Fail EXCEPTION;
BEGIN
-- Check for product availability
BEGIN
SELECT *
INTO PRODUCT_LIST
FROM PRODUCT
WHERE DISCONTINUED = 'N'; -- select all orders available
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('ERROR ! PRODUCT IS UNAVAILABLE');
RAISE Fail;
END;
--generate new order ID
SELECT MAX(ORDER_ID)+1
INTO p_order_id
FROM ORDER_DETAIL;
-- INSERTING A NEW ORDER
INSERT INTO ORDER_DETAIL VALUES (p_order_id, p_product_name, p_unit_price, p_quantity, p_discount);
COMMIT;
DBMS_OUTPUT.PUT_LINE('DONE!');
EXCEPTION
WHEN Fail THEN
ROLLBACK;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(SQLERRM);
ROLLBACK;
END INSERT_ORDER_DETAIL;
/
You have two simple approaches, implement either of them.
In your insert procedure, add an IF condition to check whether the product is available in the inventory against the input order, and put the INSERT statement inside the IF block. Else, raise an EXCEPTION product not available. Similarly check for quantity as well.
Or,
Create a FUNCTION based on above logic that returns TRUE if product exists. You could simply go for the count in the table for that matching product in the function.
Based on the function's return value TRUE, call the INSERT procedure. Else, if FALSE, raise an exception that product is not available.
Put all the functions, procedures in one package.
I am new in PL SQL and I am trying to resolve problem with copy-past data from .CVS file to database
I create a small application which will take data from .CVS and past it to database.
I create a method, but after I compile it's writtend Successfully compiled
But when I run form I get error
WHEN-BUTTON-PRESSED trigger raise unhendled exception ORA-01407
Does anyone know what this means since I google it and could not find anything ?
I would be very thankfull
declare
import_file text_io.file_type;
import_file_name varchar2(1000);
import_log_file text_io.file_type;
import_log_file_name varchar2(1000);
vec_importovano number;
brojac number;
brojac_redova number;
linebuf varchar2(5000);
p_rbr varchar2(4);
p_polica varchar2(20);
p_banka varchar2 (20);
p_kontakt varchar2(20);
kraj_fajla number;
begin
import_file_name := :Global.Lokacija_prenosa||:import.naziv_fajla||:Global.Ekstenzija_prenosa;
import_file := text_io.fopen(import_file_name,'r');
--p_rbr := 100000;
delete from zivot_trajni_nalog_ponude where banka is not null;
commit;
kraj_fajla := 0;
while kraj_fajla = 0 loop
begin
text_io.get_line(import_file, linebuf);
if brojac_redova>=2 then
if length(linebuf)>100 then
p_rbr:=substr(linebuf, 1, instr(linebuf,';',1,1)-1);
p_polica:=substr(linebuf, instr(linebuf,';',1,1)+1, instr(linebuf,';',1,2) - instr(linebuf,';',1,1)-1);
p_banka:=substr(linebuf, instr(linebuf,';',1,2)+1, instr(linebuf,';',1,3) - instr(linebuf,';',1,2)-1);
p_kontakt:=substr(linebuf, instr(linebuf,';',1,3)+1, instr(linebuf,';',1,4) - instr(linebuf,';',1,3)-1);
select count(*)
into vec_importovano
from ZIVOT_TRAJNI_NALOG_PONUDE
where broj_police=p_polica and p_rbr=redni_broj;
if vec_importovano=0 then
insert into ZIVOT_TRAJNI_NALOG_PONUDE values(p_rbr, p_polica, p_banka, p_kontakt);
commit;
end if;
end if;
end if;
EXCEPTION WHEN NO_DATA_FOUND THEN kraj_fajla := 1;
end;
end loop;
update zivot_trajni_nalog_ponude set redni_broj = p_rbr;
commit;
text_io.fclose(import_file);
message('Zavrseno prepisivanje fajla');
end;
The error you got (ORA-01407) means that you are trying to update a column (which is set to NOT NULL) with a NULL value. That won't work. For example:
SQL> create table test (id number not null);
Table created.
SQL> insert into test (id) values (100);
1 row created.
SQL> update test set id = null;
update test set id = null
*
ERROR at line 1:
ORA-01407: cannot update ("SCOTT"."TEST"."ID") to NULL
SQL>
The only UPDATE in your code is this:
UPDATE zivot_trajni_nalog_ponude SET redni_broj = p_rbr;
Apparently, p_rbr is NULL, redni_broj won't accept it and you got the error.
What to do? Debug your code and see why p_rbr doesn't have a value. A simple "solution" might be
IF p_rbr IS NOT NULL
THEN
UPDATE zivot_trajni_nalog_ponude
SET redni_broj = p_rbr;
END IF;
Also, although not related to your problem: don't COMMIT within a loop.
ORA-01407 occurs as you are trying to update/Insert a column to NULL
when the column does not accept NULL values.
To find all the "not null" columns in table ZIVOT_TRAJNI_NALOG_PONUDE, Please check the DDL of the table.
I've made a simple DVD store database. The DVD table has a column "status" which can be either 'FOR_RENT','FOR_SALE','RENTED',or 'SOLD'. I want to write a trigger to block any insertions into my RENTALS table if the status column in the DVD table is not set to 'FOR_RENT'.
Much of the documents I've looked at generally don't show example using values from two different tables so I'm a bit flummaxed.
This is what I believe has been my best attempt so far:
CREATE OR REPLACE TRIGGER RENTAL_UNAVAILABLE
BEFORE INSERT ON RENTAL;
FOR EACH ROW
WHEN (DVD.STATUS != 'FOR_RENT')
DECLARE
dvd_rented EXCEPTION;
PRAGMA EXCEPTION_INIT( dvd_rented, -20001 );
BEGIN
RAISE dvd_rented;
EXCEPTION
WHEN dvd_rented THEN
RAISE_APPLICATION_ERROR(-20001,'DVD has been rented');
END;
/
I'm getting this error:
ORA-00911: invalid character
Try this - I have not complied the code, but should be good. In case you see any compilation issues let me know and post schema on sqlfiddle.com
CREATE OR REPLACE TRIGGER rental_unavailable
BEFORE INSERT
ON rental
FOR EACH ROW
DECLARE
dvd_rented EXCEPTION;
PRAGMA EXCEPTION_INIT (dvd_rented, -20001);
n_count NUMBER (1);
BEGIN
SELECT COUNT (*)
INTO n_count
FROM dvd
WHERE dvd_id = :NEW.dvd_id AND dvd.status = 'FOR_RENT' AND ROWNUM < 2;
IF n_count > 0
THEN
RAISE dvd_rented;
END IF;
EXCEPTION
WHEN dvd_rented
THEN
raise_application_error (-20001, 'DVD has been rented');
END;