how to check what the value of Parameter in Oracle PLSQL Procedure - oracle

I am in need of amending a procedure to include new data in which a parameter has been set. I need to check the value of the parameter so that I can test my code individually before it is implemented. below is portion of code which has parameter.
PROCEDURE Get_All_MT (i IN NUMBER)
AS
BEGIN
INSERT INTO mrr_reten_mt_obp_cli (
AMI_SCHEMA,
UAN,
PRODUCT_CLASS,
POL_NO
)
SELECT a.ami_schema,
a.uan,
a.product_class,
a.pol_no
FROM mrr_retention_c_cover_item a,
att_axa_uan agt,
amt_structure str
WHERE a.accident_date BETWEEN TRUNC (ADD_MONTHS (SYSDATE, i - 1), 'MONTH')
AND TRUNC (ADD_MONTHS (SYSDATE, i), 'MONTH')
- (1 / (60 * 60 * 24))
As you can see parameter "I" is been used in for accident_date range. I need to know what is the value of I so that it can be replaced while the code is been executed individually.

Log the value using DBMS_OUTPUT:
PROCEDURE Get_All_MT (i IN NUMBER)
AS
BEGIN
DBMS_OUTPUT.PUT_LINE( i );
INSERT INTO ...

I would create table log_params (param varchar2(30), value varchar2(200), log_time date); and procedure:
create or replace procedure log_param(param varchar2(30), value varchar2(200)) as
pragma autonomous transaction
begin
insert into log_params values (param, value, sysdate);
commit;
end;
/
And include in your code: log_param('i', i);. Then examinate results in table log_params

Related

how to add audit table in package to capture timing in oracle

creating a package
inside package create 2 procedure and 2 function
now add audit to capture start timing and end timing for each procedure and function in
audit table
TBL_AUDIT_LOG(process_name,start_time,end_time,created_by,created_dttm)
Although you can create a table within a package (actually, its procedure) using dynamic SQL (see execute immediate), you shouldn't do that. That's bad practice. Just create the table at SQL level as
create table TBL_AUDIT_LOG
(process_name varchar2(60),
start_time date,
end_time date,
created_by varchar2(30),
created_dttm date);
and use it from within the package. I'd suggest you NOT to insert directly into the table from every program unit in the package - create yet another, logging procedure which will accept certain parameters and perform logging itself, possibly as an autonomous transaction. Something like this:
procedure p_log (par_proc_name in varchar2, par_start in date, par_end in date) as
begin
insert into tbl_audit_log (process_name, start_time, end_time, created_by, created_dttm)
values (par_proc_name, par_start, par_end, user, sysdate);
commit;
end;
I would create a procedure for logging :
PROCEDURE INSERT_LOG(P_FROM IN VARCHAR2,
P_START_DATE IN DATE,
P_END_DATE IN DATE) IS
BEGIN
INSERT INTO TBL_AUDIT_LOG VALUES (P_FROM , P_START_DATE, P_START_DATE,USER, NULL);
COMMIT;
END;
Not: i am not sure what is created_dttm - so i passed null.
And inside your procedures, you can use it like this :
PROCEDURE TEST_P(P_VAR IN NUMBER) IS
C_LOG_START DATE;
C_LOG_END DATE;
BEGIN
C_LOG_START := SYSDATE ;
/*
YOUR PROC LOGÄ°C
*/
C_LOG_END := SYSDATE ;
-- CALL LOG ROC HERE
INSERT_LOG('TEST_P',C_LOG_START,C_LOG_END,NULL);
END;
its smiliar with functions, but you have to declare your functions like this :
FUNCTION GET_CUSTOMER(REFNO VARCHAR2) RETURN TBL_CUSTOMER_PROFILE IS
PRAGMA AUTONOMOUS_TRANSACTION;
IS_NODATA BOOLEAN;
LORESULT TBL_CUSTOMER_PROFILE;
BEGIN
/*function logic*/
END;
Check here , it is very important :

Oracle converting a function to a trigger

I have the following function, which works,that I would like to convert into a INSERT/UPDATE
trigger for the column hash_pk. I'm struggling with syntax errors trying to convert this to a trigger. Could someone please help me out.
Secondly, would it be more efficient to store the column hash_pk as a RAW(if so how big) instead of a VARCHAR2?
Thanks in advance to all that answer.
CREATE or REPLACE FUNCTION HASH_SHA512 (
psINPUT IN VARCHAR2
) RETURN VARCHAR2 AS
rHash RAW (512);
BEGIN
rHash := DBMS_CRYPTO.HASH (TO_CLOB (psINPUT),
dbms_crypto.HASH_SH512);
RETURN ((RAWTOHEX (rHash)));
END HASH_SHA512;
/
CREATE table t(
seq_num integer GENERATED BY DEFAULT AS IDENTITY (START WITH 1) NOT NULL,
hash_pk VARCHAR2(1000) not NULL PRIMARY KEY,
c CLOB,
create_date DATE DEFAULT SYSDATE
);
/
create or replace
trigger hash_trg
before insert or update on t
for each row
begin
:new.hash_pk := HASH_SHA512(:new.c);
end;
insert into t (c) values (
rpad('z',16,'z')
);
SELECT * from t
SEQ_NUM HASH_PK C CREATE_DATE
1 2C9437F9D8FB13FC959CA2B9D5B81958B5A32556C60E35D66D1DA92227593A14316FD32EE2B3EEE06EECB1484A0CACAE61A4F930E772BB78AC84E75948DAA628 zzzzzzzzzzzzzzzz 12-OCT-21
update t set c='Good Bye';
SELECT * from t;
SEQ_NUM HASH_PK C CREATE_DATE
1 DCBC14FA2F46F1E264BBD52C4A3DF87E32CC511B43FD9AD722EACCFCA6D8CBE398D10E61E83A85625C7CF96E70348F2D33595196577B01C488030E560A7D34F7 Good Bye 12-OCT-21
I got it was missing parenthesis
create or replace
trigger hash_trg
before insert or update on t
for each row
begin
:new.hash_pk := DBMS_CRYPTO.HASH ((:new.c),
dbms_crypto.HASH_SH512);
end;

update query adding old data too even after changing id

Create a procedure that accepts 2 parameters represented the inv_id, and the percentage increase in price. The pseudo function should first update the database with the new price then return the new price and the quantity on hand.
Create a second procedure called L4Q3 that accepts the inv_id and the percentage increase in price. The procedure will use the old procedure to display the new value of the inventory (hint: value = price X quantity on hand)
CREATE OR REPLACE PROCEDURE ex3 (p_inv_id IN NUMBER, p_change IN NUMBER,
p_new_price OUT NUMBER, p_qoh OUT NUMBER)
AS
v_new_price NUMBER(6,2);
v_qoh NUMBER(6,2);
BEGIN
UPDATE inventory
SET inv_price = (SELECT inv_price + (inv_price*(p_change/100))
FROM inventory
WHERE inv_id = p_inv_id);
COMMIT;
SELECT inv_price, inv_qoh
INTO p_new_price, p_qoh
FROM inventory
WHERE inv_id = p_inv_id;
COMMIT;
v_qoh := p_qoh;
v_new_price := p_new_price;
DBMS_OUTPUT.PUT_LINE('hello'||v_new_price);
END;
/
CREATE OR REPLACE PROCEDURE use_ex3 ( p_inv_id NUMBER, p_change NUMBER)
AS
v_new_price NUMBER(6,2);
v_qoh NUMBER(6,2);
v_value NUMBER(10,2);
BEGIN
ex3(p_inv_id, p_change, v_new_price, v_qoh);
v_value := v_new_price*v_qoh;
DBMS_OUTPUT.PUT_LINE('value is:'||v_value);
END;
/
Consider converting your procedures like those below :
SQL> set serveroutput on;
SQL> CREATE OR REPLACE PROCEDURE ex3(p_inv_id IN inventory.inv_id%type,
p_change IN NUMBER,
p_new_price OUT inventory.inv_price%type,
p_qoh OUT inventory.inv_qoh%type) AS
BEGIN
UPDATE inventory
SET inv_price = inv_price * ( 1 + (p_change / 100) )
WHERE inv_id = p_inv_id
RETURNING inv_price, inv_qoh
INTO p_new_price, p_qoh;
DBMS_OUTPUT.PUT_LINE('hello '|| p_new_price);
END;
/
SQL> CREATE OR REPLACE PROCEDURE use_ex3(p_inv_id inventory.inv_id%type, p_change NUMBER) AS
v_new_price inventory.inv_price%type;
v_qoh inventory.inv_qoh%type;
v_value NUMBER(10, 2);
BEGIN
ex3(p_inv_id, p_change, v_new_price, v_qoh);
v_value := v_new_price * v_qoh;
DBMS_OUTPUT.PUT_LINE('value is: '|| v_value);
END;
the core issue is
missing filter WHERE inv_id = p_inv_id in the UPDATE statement.
i.e. not restricted to only one inv_id
Moreover considering below matters will make your code better :
don't need a subquery for the SET clause, just an assignment needed as inv_price = inv_price * ( 1 + (p_change / 100) )
had better defining variable types for columns as
inventory.<column_name>%type
extra local variables are not needed such as v_new_price, out
parameters of the procedures such as p_new_price might be used as
the assignment targets
SELECT statement after UPDATE is not needed, using RETURNING
INTO is enough
don't forget to use set serveroutput on to print out the results
I think it's a good habit to exclude commit in individual program
units to provide transaction integrity for data consistency in the
tables which got DML. Prefer keep only one commit inside the caller
application at the end of all statements and program units.

how to use date in where clause while inserting values into table using PLSQL store procedure

This is the code i used in stored procedure;
CREATE OR REPLACE PROCEDURE MY_STORE_PROCEDURE (new_date in date)
IS
BEGIN
execute immediate 'INSERT INTO TEMP_1 ( ID CHAR(10),
A_CNT NUMBER,
JOIN_DT DATE,
)
SELECT
L1.ID,
L1.A_CNT,
L1.JOIN_DT,
FROM ACTVY_1 L1
WHERE L1.JOIN_DT = new_date';
END;
===========================================================
Below is the code i used to call store procedure with passing value. value is date which store procedure reciece and used to pull date from a table. but it is giving me error.
DECLARE
a_date DATE;
BEGIN
a_date :=to_DATE ('01-NOV-2013', 'DD-MON-YYYY');
MY_STORE_PROCEDURE(a_date);
END;
Please suggest is there any syntax error or what is issue.
Based on your example, there is no reason to use dynamic SQL. You also have a bunch of errors. Try this:
CREATE OR REPLACE PROCEDURE MY_STORE_PROCEDURE (new_date IN DATE)
IS
BEGIN
INSERT INTO TEMP_1 (ID, A_CNT, JOIN_DT)
SELECT L1.ID, L1.A_CNT, L1.JOIN_DT
FROM ACTVY_1 L1
WHERE L1.JOIN_DT = new_date;
END;

How do I return a table using a procedure that has a cursor in it ? PL/SQL

I have a procedure that is given one value as input, after doing some process, using a cursor within that procedure, i want the procedure to return a table.
this one value that is given as an input_param is a non unique ID that is used to identify multiple rows.
so that way I can run a command like :
select * from {call(procedure_name(input_Param)}
My knowledge of PLSQL is limited.
I'm not sure if a procedure can have a a cursor definition inside it, and if that is possible then how do i return an entire Table from the procedure.
BTW: This procedure has to be called using a select statement, and if not a select statement then it should return a table, with a select * at the end.
If I have to specify whih columns to output instead of select * do I need to provide all those column names as input_Params ? ie. If I want the procedure to return only a small number of columns what do I do?
Thanks
You need to use PIPELINED function. Example below, link to more information at the end.
CREATE TABLE test_pipe (
id NUMBER,
name VARCHAR2(20),
salary NUMBER
);
INSERT INTO test_pipe VALUES (1, 'Smith', 5000);
INSERT INTO test_pipe VALUES (2, 'Brown', 8000);
INSERT INTO test_pipe VALUES (3, 'Bay', 10000);
COMMIT;
CREATE TYPE t_pipe_row_test AS OBJECT (
name VARCHAR2(20),
salary NUMBER
);
/
CREATE TYPE t_pipe_test_tab IS TABLE OF t_pipe_row_test;
/
CREATE OR REPLACE FUNCTION test_func_pipe(p_min_salary IN NUMBER)
RETURN t_pipe_test_tab
PIPELINED
AS
BEGIN
FOR v_rec IN (SELECT name, salary
FROM test_pipe
WHERE salary >= p_min_salary)
LOOP
PIPE ROW (t_pipe_row_test(v_rec.name, v_rec.salary));
END LOOP;
END;
/
SELECT * FROM TABLE(test_func_pipe(6000));
Output:
NAME SALARY
-------------------- ----------
Brown 8000
Bay 10000
More about pipelined functions by Tim Hall

Resources