PL/SQL procedure to run some statements and then log the result in a table - plsql

I need to automate the following set of instructions with a pl/sql procedure:
SET DEFINE OFF;
TRUNCATE TABLE EMP.dept;
INSERT INTO EMP.dept values....;
Commit;
Also,I need to log the activity(sucess/failure) into a table EMP.Log.
Can someone help me in this ?

Depending on what the columns are in the EMP.dept table I would use a procedure defined as:
--The parameters to this procedure depend on the fields in EMP.dept
--This example assumes EMP.dept has only 2 VARCHAR fields, but
--the parameter list can easily be modified:
--
CREATE OR REPLACE PROCEDURE PROC_NAME1(INPUT1 IN VARCHAR2, INPUT2 IN VARCHAR2) AS
V_FAILURE INTEGER;
BEGIN
V_FAILURE := 0;
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE EMP.dept';
INSERT INTO EMP.dept (FIELD1, FIELD2) VALUES (INPUT1, INPUT2);
COMMIT;
EXCEPTION
WHEN OTHERS THEN
V_FAILURE := 1;
ROLLBACK;
END;
BEGIN
--DEPENDING ON THE COLUMNS IN YOUR LOG_TABLE
--
INSERT INTO LOG_TABLE(STATUS, RUN_DATE)
VALUES (V_FAILURE, SYSDATE);
COMMIT;
EXCEPTION
WHEN OTHERS THEN NULL;
END;
END;

Related

Procedure run details for a day

Please let me know if you can provide the detail of “number of times” a procedure has been called for that particular day, for the all the valid procedures.
You can use your own logging technic. For example first you can create a table under the same schema of your desired procedure. Then after begin statement end before end statement in that invoked procedure, you can insert logs to newly created log table of yours.
CREATE TABLE SCHEMA.LOGTABLE
(
DATECOLUMN DATE DEFAULT SYSTIMESTAMP,
PROCNAME VARCHAR2 (200 CHAR),
TABLENAME VARCHAR2 (200 CHAR),
MESSAGE VARCHAR2 (1000 CHAR),
LOGSEQUENCE NUMBER
);
CREATE OR REPLACE PROCEDURE SCHEMA.PROCNAME IS
BEGIN
INSERT INTO SCHAME.LOGTABLE(DATECOLUMN,
PROCNAME,
TABLENAME,
MESSAGE,
LOGSEQUENCE)
VALUES (SYSTIMESTAMP,
'SCHEMA.PROCNAME',
'SCHEMA.TABLENAME',
'Proc STARTED',
NULL,
SCHEMA.SEQ_SISTEM_LOG.NEXTVAL);
COMMIT;
.....
INSERT INTO SCHAME.LOGTABLE(DATECOLUMN,
PROCNAME,
TABLENAME,
MESSAGE,
LOGSEQUENCE)
VALUES (SYSTIMESTAMP,
'SCHEMA.PROCNAME',
'SCHEMA.TABLENAME',
'Proc ENDED',
NULL,
SCHEMA.SEQ_SISTEM_LOG.NEXTVAL);
COMMIT;
END;

dynamically change column in oracle cursor

I have 50 columns in one table and need to update each column.
Trying the below plsql code. (commented update section is working).
But dynamically generated column is not accepting.
(PL/SQL: ORA-01747: invalid user.table.column, table.column, or column specification)
Anybody can help please?
DECLARE
cursor udas is
select 5109 as udaid from dual
union all
select 8209 as udaid from dual;
BEGIN
for uda in udas loop
DECLARE
cursor c1 is
select
x.item, x.uda_id, x.uda_value, x.uda_value_desc
from
hp2_uda_data x
where
x.uda_type='LOV'
and x.uda_id=uda.udaid;
begin
for i in c1 loop
begin
/*update testtable set item_uda_5109_v=i.uda_value,
item_uda_5109_d=i.uda_value_desc where item_code=i.item;*/
update testtable set 'item_uda_'||uda.udaid||'_v'=i.uda_value,
'item_uda_'||uda.udaid||'_d'=i.uda_value_desc where item_code=i.item;
end;
end loop;
commit;
end;
end loop;
END;
Dynamic code requires execute immediate:
execute immediate
'update testtable
set item_uda_'||uda.udaid||'_v = :b1
, item_uda_'||uda.udaid||'_d = :b2
where item_code = :b3'
using i.uda_value, i.uda_value_desc, i.item;
It can be useful to construct the dynamic code in a variable so that you can report or log it in the event of failure.
I also recommend looking into code indentation as a useful technique for making code readable.

PL/SQL Stored procedure

I want to delete record from table based on id using stored procedure. Id value has to be passed as parameter. But while trying this code, data in the table is not deleted. Can anyone help me to get through this
create or replace procedure PROC_INV_DELETE(num in number)
is
begin
delete from table_name
where id = '&num';
commit;
end;
/
This would do your job :
create or replace procedure PROC_INV_DELETE(num in number)
is
begin
delete from table_name
where id = num; ---No need to use & and '' here
commit;
end;
/
Calling:
declare
a number:= '&num' ;
Begin
PROC_INV_DELETE(a);
end;
/
Enter value for num: 4
old 3: a number:= '&num' ;
new 3: a number:= '4' ;
PL/SQL procedure successfully completed.

Insertion using triggers by passing values

Lets say I have a table as follows--
create table employees
(
eno number(4) not null primary key,
ename varchar2(30),
zip number(5) references zipcodes,
hdate date
);
And I'm trying to create a trigger with--
CREATE OR REPLACE TRIGGER TWELVE_ONE
BEFORE INSERT OR UPDATE
ON EMPLOYEES
FOR EACH ROW
DECLARE
V_DATE VARCHAR2 (10);
BEGIN
SELECT TO_CHAR (SYSDATE, 'hh24:mi:ss') INTO V_DATE FROM DUAL;
IF (V_DATE >= '12:00:01' AND V_DATE < '13:00:00')
THEN
INSERT INTO TABLE ?????
ELSE
ROLLBACK? TERMINATE TRANSACTION?
END IF;
END;
Purpose of the trigger is to allow an insertion/update during 12:00-13:00 and prevent the insertion at any other time. The trigger construction (thanks to #Melkikun) is seems ok. However now I'm facing the following issues--
How is it possible to pass the values here? I mean lets say my create statement is:
Insert into employees Values (1, 'someone', 11111, '17-12-2015')
And lets say the time is 12:30:01 now. How would the trigger perform the insertion without knowing the values?
And lets say the time is now 13:00:1 now. How would the trigger stop/prevent the insertion?
I'm using Oracle SQL Developer 4.02.15
Many Thanks
You just have to do it the other way.
If the time is not correct,then you raise an exception, so the insert won't be done.
CREATE OR REPLACE TRIGGER TWELVE_ONE
BEFORE INSERT OR UPDATE
ON EMPLOYEES
FOR EACH ROW
DECLARE
V_DATE VARCHAR2 (10);
MyException exception;
BEGIN
SELECT TO_CHAR (SYSDATE, 'hh24:mi:ss') INTO V_DATE FROM DUAL;
IF (V_DATE < '12:00:01' OR V_DATE > '13:00:00')
THEN
raise MyException;
END IF;
EXCEPTION
When MyException then
ROLLBACK;
//output message ...
END;
How would the trigger perform the insertion without knowing the values?
The trigger knows the value thanks to :NEW and :OLD.
You normally use the terms in a trigger using :old to reference the old value and :new to reference the new value.So you will have :NEW.eno ,:NEW.ename ...
Here is an example from the Oracle documentation :
CREATE OR REPLACE TRIGGER Print_salary_changes
BEFORE DELETE OR INSERT OR UPDATE ON Emp_tab
FOR EACH ROW
WHEN (new.Empno > 0)
DECLARE
sal_diff number;
BEGIN
sal_diff := :new.sal - :old.sal;
dbms_output.put('Old salary: ' || :old.sal);
dbms_output.put(' New salary: ' || :new.sal);
dbms_output.put_line(' Difference ' || sal_diff);
END;

In pl/sql how can I execute a select statement stored in CLOB type of field?

In Oracle DB, I have a large select staetment with lots of joins and cases that is stored in a CLOB field in one of my tables.
How can i execute this statement from the CLOB?
Look into the EXECUTE IMMEDIATE syntax.
Example table:
CREATE TABLE test(id number, largedata clob);
INSERT INTO test VALUES (1, 'select name from v$database');
commit;
select * from test;
DECLARE
l_sql clob;
l_result VARCHAR2(50);
BEGIN
SELECT LARGEDATA INTO l_sql FROM TEST;
EXECUTE IMMEDIATE l_sql INTO l_result;
dbms_output.put_line(l_result);
END;
/
Output is the DB name.

Resources