trigger is not updating table - oracle

I created a trigger that updates a table I created whenever I update a column in a different table. So far my trigger compiles but when I updated the column the trigger doesn't seem to fire or do anything.
Can anyone help me?
CREATE TABLE bb_sales_sum (
idProduct number(2) NOT NULL,
total number(6,2),
quantity number);
CREATE OR REPLACE TRIGGER BB_SALESUM_TRG
AFTER UPDATE OF orderplaced on bb_basket
FOR EACH ROW
WHEN (NEW.orderplaced = 1)
DECLARE
lv_count Number;
BEGIN
if :new.orderplaced = 1 then
for item in
(select idproduct, (quantity * price) AS total, quantity
from bb_basketitem
where idbasket = :old.idbasket)
loop
select count(*)
into lv_count
from bb_sales_sum where idProduct = item.idproduct;
if lv_count = NULL then
INSERT INTO bb_sales_sum
VALUES (item.idproduct, item.total, item.quantity);
else
update bb_sales_sum
set quantity = item.quantity where
idProduct = item.idproduct;
end if;
end loop;
end if;
END;
/
update bb_basket
set orderplaced = 1
where idbasket = 14;
select * from bb_sales_sum;

You may use a similar MERGE statement using the values from bb_basketitem instead of a for loop.
CREATE OR REPLACE TRIGGER BB_SALESUM_TRG
AFTER UPDATE OF orderplaced on bb_basket
FOR EACH ROW
WHEN (NEW.orderplaced = 1)
BEGIN
MERGE INTO bb_sales_sum t USING
( select idproduct, (quantity * price) AS total, quantity
from bb_basketitem item
where idbasket = :old.idbasket
) s
ON (s.idproduct = t.idproduct )
WHEN MATCHED THEN UPDATE
SET quantity = s.quantity
WHEN NOT MATCHED THEN
INSERT (
idproduct,quantity,total)
VALUES
( s.idproduct,s.quantity,s.total );
END;
/
DEMO

Related

how can i put a query in decode function?

create table ss( no number, filepath varchar2(300) )
I want to have 5 or less duplicate values of 'no' in this table
when select count(no) from ss where no=#{no} <5, insert into ss values({no},{filepath})
so duplicate values of 'no' can't be over 5.
how can i do this?
You could create a similar trigger to implement this logic:
CREATE OR REPLACE TRIGGER set_no_ss_tbl_trg
BEFORE INSERT ON ss_tbl
FOR EACH ROW
BEGIN
DECLARE
l_cnt_no NUMBER;
BEGIN
SELECT COUNT(1)
INTO l_exceeding
FROM g_piece
WHERE refdoss = :new.no;
IF l_cnt_no > 5 THEN
SELECT MIN(no)
INTO :new.no
FROM (SELECT COUNT(1), no
FROM ss_tbl
GROUP BY no
HAVING COUNT(1) + 1 <= 5);
END IF;
END;
END;

Trigger that changes value in another table /plsql

I've created two tables: Employees and Departments
CREATE TABLE EMP
( emp_id number(3) PRIMARY KEY,
dept_id Number(3) NOT NULL,
emp_name Varchar2(50) NOT NULL,
address Varchar2(100),
phone Varchar2(20) NOT NULL,
salary Number(8,2) NOT NULL,
CONSTRAINT fk_DEPT FOREIGN KEY (dept_id) REFERENCES DEPT(DEPT_ID));
CREATE TABLE DEPT
( dept_id number(3) PRIMARY KEY,
dept_name varchar2(50) NOT NULL,
emp_cnt Number(3) NOT NULL)
I need to create trigger that changes value in DEPT.emp_cnt after inserting or deleting data in EMP table.
Here is my attempt
create or replace trigger add_emp_to_the_dep
after insert or delete on EMP
for each row
begin
update DEPT
set emp_cnt = :new.emp_id
where DEPT.dept_id = :new.dept_id;
if INSERTING then
emp_cnt += 1;
else DELETING then
emp_cnt -= 1;
end if;
end;
Wrong syntax; there's no such thing as emp_cnt += 1; in Oracle's PL/SQL.
Try something like this instead:
create or replace trigger add_emp_to_the_dep
after insert or delete on emp
for each row
begin
if inserting then
update dept set
emp_cnt = emp_cnt + 1
where dept_id = :new.dept_id;
elsif deleting then
update dept set
emp_cnt = emp_cnt - 1
where dept_id = :old.dept_id;
end if;
end;
/
You can use a compound trigger to collate the changes and make the minimum number of updates:
CREATE TRIGGER add_emp_to_the_dep
FOR INSERT OR UPDATE OR DELETE ON emp
COMPOUND TRIGGER
TYPE ids_type IS TABLE OF EMP.DEPT_ID%TYPE;
TYPE cnt_type IS TABLE OF PLS_INTEGER;
TYPE idx_type IS TABLE OF PLS_INTEGER INDEX BY PLS_INTEGER;
ids ids_type := ids_type();
cnts cnt_type := cnt_type();
idxs idx_type := idx_type();
PROCEDURE modify_dept_cnt (
id EMP.DEPT_ID%TYPE,
cnt PLS_INTEGER
)
IS
BEGIN
IF id IS NULL THEN
RETURN;
END IF;
IF NOT idxs.EXISTS(id) THEN
ids.EXTEND;
cnts.EXTEND;
ids(ids.COUNT) := id;
cnts(cnts.COUNT) := cnt;
idxs(id) := ids.COUNT;
ELSE
cnts(idxs(id)) := cnts(idxs(id)) + cnt;
END IF;
END modify_dept_cnt;
AFTER EACH ROW
IS
BEGIN
modify_dept_cnt(:NEW.DEPT_ID, 1);
modify_dept_cnt(:OLD.DEPT_ID, -1);
END AFTER EACH ROW;
AFTER STATEMENT
IS
BEGIN
FORALL i IN 1 .. ids.count
UPDATE dept
SET emp_cnt = emp_cnt + cnts(i)
WHERE dept_id = ids(i);
END AFTER STATEMENT;
END;
/
Then, if you do:
INSERT INTO emp (emp_id, dept_id, emp_name, phone, salary)
SELECT 1, 1, 'Alice', '0', 100 FROM DUAL UNION ALL
SELECT 2, 1, 'Betty', '1', 100 FROM DUAL UNION ALL
SELECT 3, 2, 'Carol', '2', 100 FROM DUAL UNION ALL
SELECT 4, 1, 'Debra', '3', 100 FROM DUAL UNION ALL
SELECT 5, 3, 'Emily', '4', 100 FROM DUAL UNION ALL
SELECT 6, 3, 'Fiona', '5', 100 FROM DUAL;
It will collate all the changes and UPDATE the DEPT table only 3 times, as employees for 3 unique DEPT_ID are added, rather than performing 6 updates, one for each inserted row.
db<>fiddle here
create or replace trigger add_emp_to_the_dep
after insert or delete on emp
for each row
begin
if inserting then
update dept set
emp_cnt = emp_cnt + 1
where dept_id = :new.dept_id;
elsif deleting then
update dept set
emp_cnt = emp_cnt - 1
where dept_id = :old.dept_id;
end if;
end;

SQL statement ignored for a index nested loop join

I'm trying to build a data warehouse based on a star schema with 5 dimension tables and 1 facts table using two sets of data, MASTERDATA which holds 100 records and DATASTREAM which holds 10,000 records.
I am reading 100 records from DATASTREAM as an input into a cursor then reading the cursor record by record and then retrieving the relevant records from MASTERDATA on the index product_id as a index nested loop join. After this I am loading the new attributes from the transaction tuple inside the relevant dimension and fact tables.
However, I have a few errors. I'm just looking for help to understand why I am getting the errors I am getting. The errors at the moment are:
Error(98,6):PL/SQL:SQL Statement Ignored
Error(101,5):PL/SQL: ORA-00933: SQL command not properly ended
Error(105,8):PLS-00103:Encountered the symbol "LOOP" when expecting one of the following: if
Error(113):PLS-00103:Encountered the symbol "end-of-file" when expecting one of the following: ;
My code:
CREATE OR REPLACE PROCEDURE transactionINLJ AS TYPE t_cursor is ref cursor;
v_cursor t_cursor;
v_cursor_records DATASTREAM%rowtype;
record_100 varchar2(300);
rec number;
v_customer_id masterdata.customer_id%type;
v_customer_account_type masterdata.customer_account_type%type;
v_product_id masterdata.product_id%type;
v_product_name masterdata.product_name%type;
v_supplier_id masterdata.supplier_id%type;
v_supplier_name masterdata.supplier_name%type;
v_outlet_id masterdata.outlet_id%type;
v_outlet_name masterdata.outlet_name%type;
v_sale_price masterdata.sale_price%type;
t_customer_id int;
t_supplier_id int;
t_product_id int;
t_outlet_id int;
t_date_id int;
t_sales_fact int;
BEGIN
rec := 1;
WHILE (rec <= 10000)
LOOP
record_100 := 'SELECT * FROM datastream WHERE datastream_id between '|| TO_CHAR(rec) ||
' and ' || TO_CHAR(rec+99);
OPEN v_cursor FOR record_100;
LOOP
FETCH v_cursor INTO v_cursor_records;
EXIT WHEN v_cursor%notfound;
SELECT product_id, product_name, supplier_id, supplier_name, sale_price
INTO v_product_id, v_product_name, v_supplier_id, v_supplier_name, v_sale_price
FROM masterdata
WHERE product_id = v_cursor_records.product_id;
SELECT COUNT(0)
INTO t_product_id
FROM product_dim
WHERE product_id = v_cursor_records.product_id;
IF t_product_id = 0 THEN
INSERT INTO product_dim(product_id, product_name)
VALUES (v_cursor_records.product_id, v_cursor_records.product_name);
END IF;
SELECT COUNT(0)
INTO t_customer_id
FROM customer_dim
WHERE customer_id = v_cursor_records.customer_id;
IF t_customer_id = 0 THEN
INSERT INTO customer_dim(customer_id, customer_name,customer_account_type)
VALUES (v_cursor_records.customer_name, v_cursor_records.customer_account_type, v_cursor_records.customer_account_type);
END IF;
SELECT COUNT(0)
INTO t_supplier_id
FROM supplier_dim
WHERE supplier_id = v_cursor_records.supplier_id;
IF t_supplier_id = 0 THEN
INSERT INTO supplier_dim(supplier_id, supplier_name)
VALUES (v_cursor_records.supplier_id, v_cursor_records.supplier_name);
END IF;
SELECT COUNT(0)
INTO t_outlet_id
FROM outlet_dim
WHERE outlet_id = v_cursor_records.outlet_id;
IF t_outlet_id = 0 THEN
INSERT INTO outlet_dim(outlet_id, outlet_name)
VALUES (v_cursor_records.outlet_id, v_cursor_records.outlet_name);
END IF;
SELECT COUNT(0)
INTO t_date_id
FROM date_dim
WHERE d_date = v_cursor_records.d_date;
IF t_date_id = 0 THEN
INSERT INTO date_dim(d_date, d_year, d_quater, d_month, d_day)
VALUES (v_cursor_records.d_date
,EXTRACT(year FROM v_cursor_records.d_date), TO_CHAR(v_cursor_records.d_date,'Q')
,EXTRACT(month FROM v_cursor_records.d_date)
,EXTRACT(day FROM v_cursor_records.d_date));
END IF;
SELECT COUNT(0)
INTO t_sales_fact
FROM sales_fact
WHERE product_id = v_cursor_records.product_id
AND customer_id = v_csr_rec.customer_id
AND supplier_id = v_csr_rec.supplier_id
AND outlet_id = v_csr_rec.outlet_id
AND d_date = v_csr_rec.d_date
AND sale_price = v_csr_rec.sale_price
AND quantity_sold = v_csr_rec.quantity_sold;
IF t_sales_fact = 0 THEN
INSERT INTO sales_fact(customer_id,product_id,outlet_id,supplier_id,d_date,sale_price,total_sale,quantity_sold)
VALUES (v_cursor_records.customer_id, v_cursor_records.product_id, v_cursor_records.outlet_id,v_cursor_records.supplier_id,
v_cursor_records.d_date, v_cursor_records.sale_price, v_cursor_records.quantity_sold*sale_price, v_cursor_records.quantity_sold)
END IF;
COMMIT;
END LOOP;
CLOSE v_cursor;
COMMIT;
rec := rec+100;
END LOOP;
END;
It is an unfortunate truth that occasionally procedural processing is required. But almost all this can be done with just SQL and a tiny bit of PL/SQL extensions. In particular there is no need to "select count..." for any of your target tables, sql handles that quite easily on the INSERT statement itself. Further there is no need to loop through a cursor on a row-by-row (aka slow-by-slow) process, instead use BULK COLLECT and FORALL to handle the entire array (100 rows in this case) all with a single INSERT for each table. With it there is no need to for loop control counters, nor calculating the ID numbers to retrieve, nor the exact the number of rows (what would happen if your source table contained 10050 or 9950 rows instead of exactly 10000). As a side effect you gain considerable performance. The following shows that process:
create or replace procedure transactioninlj as
k_bulk_buffer_size constant integer := 100;
cursor v_cursor is
select d.customer_id
, d.outlet_id
, d.outlet_name
, d.customer_name
, d.customer_account_type
, d.d_date
, d.quantity_sold
, m.product_id
, m.product_name
, m.supplier_id
, m.supplier_name
, m.sale_price
from datastream d
join masterdata m on m.product_id = d.product_id
;
type t_cursor_records is table of v_cursor%rowtype;
v_cursor_records t_cursor_records;
begin
open v_cursor;
loop
fetch v_cursor
bulk collect
into v_cursor_records
limit k_bulk_buffer_size;
forall v_index in 1 .. v_cursor_records.count
insert into product_dim(product_id, product_name)
select v_cursor_records(v_index).product_id
, v_cursor_records(v_index).product_name
from dual
where not exists
( select null
from product_dim
where product_id = v_cursor_records(v_index).product_id
);
forall v_index in 1 .. v_cursor_records.count
insert into supplier_dim(supplier_id, supplier_name)
select v_cursor_records(v_index).supplier_id
, v_cursor_records(v_index).supplier_name
from dual
where not exists
( select null
from supplier_dim
where supplier_id = v_cursor_records(v_index).supplier_id
);
forall v_index in 1 .. v_cursor_records.count
insert into customer_dim(customer_id, customer_name,customer_account_type)
select v_cursor_records(v_index).customer_id
, v_cursor_records(v_index).customer_name
, v_cursor_records(v_index).customer_account_type
from dual
where not exists
( select null
from customer_dim
where customer_id = v_cursor_records(v_index).customer_id
);
forall v_index in 1 .. v_cursor_records.count
insert into outlet_dim(outlet_id, outlet_name)
select v_cursor_records(v_index).outlet_id
, v_cursor_records(v_index).outlet_name
from dual
where not exists
( select null
from outlet_dim
where outlet_id = v_cursor_records(v_index).outlet_id
);
forall v_index in 1 .. v_cursor_records.count
insert into date_dim(d_date, d_year, d_quater, d_month, d_day)
select v_cursor_records(v_index).d_date
, extract(year from v_cursor_records(v_index).d_date)
, to_char(v_cursor_records(v_index).d_date,'Q')
, extract(month from v_cursor_records(v_index).d_date)
, extract(day from v_cursor_records(v_index).d_date)
from dual
where not exists
( select null
from outlet_dim
where outlet_id = v_cursor_records(v_index).outlet_id
);
forall v_index in 1 .. v_cursor_records.count
insert into sales_fact( customer_id
, product_id
, outlet_id
, supplier_id
, d_date
, sale_price
, total_sale
, quantity_sold
)
select v_cursor_records(v_index).customer_id
, v_cursor_records(v_index).product_id
, v_cursor_records(v_index).outlet_id
, v_cursor_records(v_index).supplier_id
, v_cursor_records(v_index).d_date
, v_cursor_records(v_index).sale_price
, v_cursor_records(v_index).quantity_sold
* v_cursor_records(v_index).sale_price
, v_cursor_records(v_index).quantity_sold
from dual
where not exists
( select null
from sales_fact
where product_id = v_cursor_records(v_index).product_id
and customer_id = v_cursor_records(v_index).customer_id
and supplier_id = v_cursor_records(v_index).supplier_id
and outlet_id = v_cursor_records(v_index).outlet_id
and d_date = v_cursor_records(v_index).d_date
and sale_price = v_cursor_records(v_index).sale_price
and quantity_sold = v_cursor_records(v_index).quantity_sold
);
exit when v_cursor_records.count < k_bulk_buffer_size;
end loop;
close v_cursor;
commit;
end transactioninlj;
Note: The DDL for the source tables is not included in your post so I had to "invent" the definition for DATASTREAM. However, you only have 2 source inputs: DATASTREAM and MASTERDATA. Since you only select 5 columns from masterdata, every thing else must come from datastream.

SQL Table is mutating... Error

I'm attempting to write a trigger that will disallow any room in a hospital to have more than 3 services. The table RoomServices has a room number and a service that it has. So the only way to determine this is to group the rooms by room number and count the services. I have tried the code:
CREATE TRIGGER RoomServiceLimit
BEFORE INSERT OR UPDATE ON RoomServices
FOR EACH ROW
DECLARE
numService NUMBER;
CURSOR C1 IS SELECT count(*) AS RoomCount FROM RoomServices WHERE roomNumber = :new.roomNumber;
BEGIN
IF(inserting) THEN
SELECT count(*) into numService FROM RoomServices WHERE roomNumber = :new.roomNumber;
if(numService > 2) THEN
RAISE_APPLICATION_ERROR(-20001,'Room ' || :new.roomNumber || ' will have more than 3 services.');
END IF;
END IF;
IF(updating) THEN
FOR rec IN C1 LOOP
IF(rec.RoomCount > 2) THEN
RAISE_APPLICATION_ERROR(-20001,'Room ' || :new.roomNumber || ' will have more than 3 services.');
END IF;
END LOOP;
END IF;
END;
/
I've tried running each method separately with insert and update, and inserting always works and updating will always give me the mutating table error. I don't know how else to go about solving this problem, so any advice would be greatly appreciated.
Thanks!
There is no reliable way to enforce this kind of constraint using triggers. One possible approach is to use a materialized view that automatically refreshes on commit and has a check constraint enforcing your business rule:
create table roomservices (
pk number not null primary key,
roomnumber number);
create materialized view mv_roomservices
refresh on commit as
select
pk,
roomnumber,
count(*) over (partition by roomnumber) as cnt
from roomservices;
alter table mv_roomservices add constraint
chk_max_2_services_per_room check (cnt <= 2);
Now, whenever you add more than two services for a room and try to commit your transaction, you will get a ORA-12008 exception (error in materialized view refresh path).
I assume that RoomServices:
a) is a small table that is not intensively modified
b) there will never exist a room with more than 3 services
Note: you say "more than 3 services" but your code says "more than 2 services". So I will use "more than 2 services".
Then, what about using a statement trigger?
CREATE OR REPLACE TRIGGER RoomServiceLimit
AFTER INSERT OR UPDATE ON RoomServices
DECLARE
badRoomsCount NUMBER;
badRoomsList VARCHAR2(32767); -- adjust the varchar2 size according to your requirements
BEGIN
SELECT COUNT(*), LISTAGG(roomNumber, ', ') WITHIN GROUP (ORDER BY 1)
INTO badRoomsCount, badRoomsList
FROM (SELECT roomNumber FROM RoomServices GROUP BY roomNumber HAVING COUNT(*) > 2);
IF (badRoomsCount > 0) THEN
RAISE_APPLICATION_ERROR(-20001,'Room/s '||badRoomsList||' will have more than 2 services.');
END IF;
END;
/
If RoomServices is small but have too many changes (inserts or updates) then you may consider create an index on RoomNumber.
If my assumptions are false try something like:
CREATE GLOBAL TEMPORARY TABLE RoomServicesAux as SELECT roomNumber FROM RoomServices WHERE 1=0;
/
CREATE OR REPLACE TRIGGER PreRoomServiceLimit
BEFORE INSERT OR UPDATE ON RoomServices
BEGIN
DELETE FROM RoomServicesAux;
END;
/
CREATE OR REPLACE TRIGGER RowRoomServiceLimit
BEFORE INSERT OR UPDATE OF roomNumber ON RoomServices FOR EACH ROW
BEGIN
INSERT INTO RoomServicesAux VALUES (:NEW.roomNumber);
END;
/
CREATE OR REPLACE TRIGGER RoomServiceLimit
AFTER INSERT OR UPDATE ON RoomServices
DECLARE
badRoomsCount NUMBER;
badRoomsList VARCHAR2(32767); -- adjust the varchar2 size according to your requirements
BEGIN
SELECT COUNT(*), LISTAGG(roomNumber, ', ') WITHIN GROUP (ORDER BY 1)
INTO badRoomsCount, badRoomsList
FROM (
SELECT roomNumber
FROM RoomServices
WHERE roomNumber in (SELECT roomNumber FROM RoomServicesAux)
GROUP BY roomNumber
HAVING COUNT(*) > 2
);
DELETE FROM RoomServicesAux;
IF (badRoomsCount > 0) THEN
RAISE_APPLICATION_ERROR(-20001,'Room/s '||badRoomsList||' will have more than 2 services.');
END IF;
END;
/
Or if you have Oracle 11g or greater then you can use a compound trigger:
CREATE OR REPLACE TYPE RoomsListType IS TABLE OF INTEGER; -- change to the type of RoomServices.rowNumber
/
CREATE OR REPLACE TRIGGER RoomServiceLimit
FOR INSERT OR UPDATE OF roomNumber ON RoomServices
COMPOUND TRIGGER
RoomsList RoomsListType := RoomsListType();
badRoomsCount NUMBER;
badRoomsList VARCHAR2(32767); -- adjust the varchar2 size according to your requirements
AFTER EACH ROW IS
BEGIN
RoomsList.EXTEND;
RoomsList(RoomsList.COUNT) := :NEW.roomNumber;
END AFTER EACH ROW;
AFTER STATEMENT IS
BEGIN
SELECT COUNT(*), LISTAGG(roomNumber, ', ') WITHIN GROUP (ORDER BY 1)
INTO badRoomsCount, badRoomsList
FROM (
SELECT roomNumber
FROM RoomServices
WHERE roomNumber in (SELECT * FROM table(RoomsList))
GROUP BY roomNumber
HAVING COUNT(*) > 2
);
IF (badRoomsCount > 0) THEN
RAISE_APPLICATION_ERROR(-20001,'Room/s '||badRoomsList||' will have more than 2 services.');
END IF;
END AFTER STATEMENT;
END;
/
Seems you cannot solve this issue without some workarounds. If there is nothing better you can find, check this out:
I guess you have table Room, otherwise create one:
alter table Room add (
servicesCount integer default 0 not null check (servicesCount <= 3)
);
Then update this number with current values (not sure if the statement is valid, it is not the key point here)
update Room r
set servicesCount = (select count(*)
from RoomServices s
where r.roomNumber = s.roomNumber);
then in your trigger
create trigger RoomServiceLimit
before insert or update on RoomServices
for each row
begin
update Room
set servicesCount = servicesCount + 1
where roomNumber = :new.roomNumber;
end;
Looks quite ugly, but, as I've told, I am not sure you can find anything better with trigger.
EDIT
The complete working example
drop table Room;
drop table RoomServices;
create table Room (
roomNumber integer primary key,
servicesCount integer default 0 not null check (servicesCount <= 3)
);
create table RoomServices (
roomNumber integer,
service varchar2(100),
comments varchar2(4000)
);
create trigger RoomServiceLimit
before insert or update or delete on RoomServices
for each row
begin
if inserting then
update Room
set servicesCount = servicesCount + 1
where roomNumber = :new.roomNumber;
elsif updating and :old.roomNumber != :new.roomNumber then
update Room
set servicesCount = servicesCount + 1
where roomNumber = :new.roomNumber;
update Room
set servicesCount = servicesCount - 1
where roomNumber = :old.roomNumber;
elsif deleting then
update Room
set servicesCount = servicesCount - 1
where roomNumber = :old.roomNumber;
end if;
end;
/
insert into Room(roomNumber) values (1);
insert into Room(roomNumber) values (2);
insert into RoomServices(roomNumber,service,comments) values (1,'cleaning','first');
insert into RoomServices(roomNumber,service,comments) values (1,'drying','second');
insert into RoomServices(roomNumber,service,comments) values (1,'watering','third');
insert into RoomServices(roomNumber,service,comments) values (1,'something','third'); -- error
select * from room;
insert into RoomServices(roomNumber,service,comments) values (2,'something','2: first');
update RoomServices
set comments = null
where roomNumber = 2;
select * from room;
update RoomServices -- error
set roomNumber = 1
where roomNumber = 2;
select * from room;
delete from RoomServices where roomNumber = 1;
select * from room;

How to write a Procedure with multiple operations like select and update

Table
Id
Count
I want to write a procedure to find 'Count' in the table with 'Id' as key.After getting 'count' i have to increment it and update back in the table for that 'Id'.How can I write this with procedure without using cursors.
I want a simple procedure like below, BUT ITS NOT EXECUTING.IT SAYS PROCEDURE SUCCESSFUL WITH COMPILATION ERRORS.Help me out.
create or replace PROCEDURE newpro( inId IN NUMBER, outcount OUT NUMBER) is
select COUNT into outcount from Table1 WHERE ID= inId ;
BEGIN
outcount := outcount +1;
update Table1 set COUNT = outcount WHERE ID = inId ;
END;
UPDATE tableName
SET "Count" = "Count" + 1
WHERE ID = valueHere
SEE SQLFiddle Demo
try this one
create or replace Procedure Newpro
(
Inid in number,
Outcount out number
) is
begin
select count + 1
into Outcount
from Table1
where Id = Inid;
update Table1
set count = Outcount
where Id = Inid;
end;

Resources