Error in PLSQL delete_document function - oracle

This is my PLSQL function to delete a document. SQLdeveloper complains. I know VARCHAR should be replaced with VARCHAR2, I am aware of that. There's something more than that. Package specification is absolutely fine.
FUNCTION delete_document (p_da_document_id IN da_documents.da_document_id%TYPE)
RETURN VARCHAR
IS
v_delete_status VARCHAR := 'N';
BEGIN
DELETE FROM da_document_key_values
WHERE da_document_id = p_da_document_id;
DELETE FROM da_document_tags
WHERE da_document_id = p_da_document_id;
DELETE FROM da_documents
WHERE da_document_id = p_da_document_id;
COMMIT;
SELECT COUNT(*) AS doc_count
FROM da_documents
WHERE da_document_id = p_da_document_id;
IF (doc_count = 0) THEN
v_delete_status := 'Y';
END IF;
RETURN v_delete_status;
END delete_document;

Just realised a procedure above has not been ended correctly. END; was missing. My mistake.

Related

Insert values from a type list PLSQL ORACLE 11

thanks for helping me.
The first insert works OK but the second doesnt insert anything. Can you help me please. Im learning plsql but there is still some things i dont know.
PROCEDURE PR_INS_INVESTIGATION (
PIN_INS_INVESTIGATION IN IN_INS_INVESTIGATION)
IS
LST_INS_INVESTIGATED RC_INS_INVESTIGATED;
EX_NO_DATA EXCEPTION;
BEGIN
INSERT INTO PQR076INVESTIGATION (CCPQR076IDINVESTIGATION,
CCPQR076DATE,
CCPQR076AREA,
CCPQR076STATE,
CCPQR076USER)
VALUES (PIN_INS_INVESTIGATION.IDINVESTIGACION,
SYSDATE,
PIN_INS_INVESTIGATION.AREA,
PIN_INS_INVESTIGATION.STATE,
USER);
COMMIT;
IF LST_INS_INVESTIGATED IS NOT NULL
AND LST_INS_INVESTIGATED.COUNT > 0
THEN
FOR j IN LST_INS_INVESTIGATED.FIRST .. LST_INS_INVESTIGATED.LAST
LOOP
INSERT INTO PQR075INVESTIGATED (CCPQR075IDINVESTIGATION,
CCPQR075NIDENT,
CCPQR075NAME,
CCPQR075USER)
VALUES (PIN_INS_INVESTIGATION.IDINVESTIGAtION,
LST_INS_INVESTIGATED (J).NUMBERID,
LST_INS_INVESTIGATED (J).NAME,
USER);
COMMIT;
END LOOP;
END IF;
END;
This is the way im testing the procedure:
´´´
declare
pin_ins_investigation in_ins_investigation;
begin
pin_ins_investigation := in_ins_investigation();
pin_ins_investigation.IDinvestigation := '1234460';
pin_ins_investigation.AREA := '05';
pin_ins_investigation.STATE := 'E';
pin_ins_investigation.LST_INS_investigated.extend;
pin_ins_investigation.LST_INS_investigated(1).NUMBERID := '1014350360';
pin_ins_investigation.LST_INS_investigated(1).NAME := 'PETER TOSH';
pkg_package.pr_ins_investigation(pin_ins_investigation => pin_ins_investigation);
end;
´´´
The way I see it, this:
IF LST_INS_INVESTIGATED IS NOT NULL
AND LST_INS_INVESTIGATED.COUNT > 0
is never true so nothing within the IF - END IF block is ever executed.
You declared it as
LST_INS_INVESTIGATED RC_INS_INVESTIGATED;
but lst_ins_investigated doesn't contain anything, it is just declared, never populated with any values. Once you fix that, code might work.

IF THEN ELSE NESTED PL/SQL ORACLE

I am a beginner using PL/SQL in oracle database, I just want to develop the coding that has been exist before. I want to put new condition and statement IF THEN ELSE NESTED after this code ELSIF updating THEN H_TYP := 'U';
But I am stuck with the my code, I have not yet find the way to fixing my code.
Here is my code;
create or replace TRIGGER TMCI_SUB_ITEM_MASTER_TR_R
AFTER DELETE OR INSERT OR UPDATE ON TMCI_SUB_ITEM_MASTER
REFERENCING OLD AS OLD NEW AS NEW
FOR EACH ROW
BEGIN
DECLARE
H_ID TMCI_SUB_ITEM_MASTER_R.HST_ID%TYPE;
H_TYP TMCI_SUB_ITEM_MASTER_R.TSK%TYPE;
rdate DATE;
t_max_rev TMCI_SUB_ITEM_MASTER_R.REV%TYPE;
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE;
BEGIN
rdate := SYSDATE;
IF INSERTING THEN H_TYP := 'I';
...
ELSIF updating THEN H_TYP := 'U';
IF H_INS_USR_ID = 'SL01' THEN
SELECT NVL(MAX(Rev), 0) INTO t_max_rev FROM TMCI_SUB_ITEM_MASTER_R WHERE ITM_CD = :old.ITM_CD;
INSERT INTO TMCI_SUB_ITEM_MASTER_R
VALUES( H_ID,
H_TYP,
:old.ITM_CD,
CASE WHEN :old.ITM_NM <> :new.ITM_NM THEN CONCAT(:new.ITM_NM,'')
ELSE :new.ITM_NM
END);
ELSE
SELECT NVL(MAX(Rev), 0) INTO t_max_rev FROM TMCI_SUB_ITEM_MASTER_R WHERE ITM_CD = :old.ITM_CD;
INSERT INTO TMCI_SUB_ITEM_MASTER_R
VALUES( H_ID,
H_TYP,
:old.ITM_CD,
CASE WHEN :old.ITM_NM <> :new.ITM_NM THEN CONCAT(:new.ITM_NM,'*')
ELSE :new.ITM_NM
END);
END IF;
ELSIF deleting THEN H_TYP := 'D';
...
END IF;
END;
END;
If I login by SL01 result will always read in the last statement (ELSE ...). It should be execute the first statement.
I need a help for fixing this problem.
It looks like you are never setting H_INS_USR_ID to any value. I assume it is meant to the user for the incoming row? If that is the case, then
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE;
becomes
H_INS_USR_ID TMCI_SUB_ITEM_MASTER_R.INS_USR_ID%TYPE := :new.INS_USR_ID;

Oracle read and return data from cursor

I'm trying to create a stored procedure in Oracle that has one input parameter and one output variable and, in case of results, return a dataset to my .Net Application. The main issue is that I can't change the signature of the procedure and need to do if condition to validate if exist records or not.
The main issue that i've being struggled is with cursors (to execute and return the information), and to count the results of the select.
Here is an example of what i'm doing to try to retrieve the data.
CREATE PROCEDURE SP_Testing (v_input IN VARCHAR2(50), v_OutID NUMBER(1))
AS
TYPE v_record_botoes IS RECORD (
v_dummy_col1 VARCHAR2(50),
v_dummy_col2 VARCHAR2(250)
);
TYPE table_botoes IS TABLE OF v_record_botoes;
tt_botoes table_botoes;
v_ref_cursor SYS_REFCURSOR;
CURSOR v_cursor IS
(SELECT dt.v_dummy_col1,
dt.v_dummy_col2
FROM dummy_table dt
WHERE v_dummy_col3 = v_input);
v_check NUMBER;
BEGIN
tt_botoes := table_botoes();
v_check := 0;
FOR v_row IN v_cursor
LOOP
tt_botoes.extend;
tt_botoes(tt_botoes.COUNT) := v_row;
END LOOP;
v_check := tt_botoes.COUNT;
-- condition that need to know the nr of records of the select
IF v_check = 0 THEN
v_OutID := 0;
ELSE
v_OutID := 1;
OPEN v_ref_cursor FOR
SELECT *
FROM tt_botoes; -- also tryed "FROM TABLE (tt_botoes)" and "FROM TABLE (cast(tt_botoes AS table_botoes))"
-- return dataset to .net application
DBMS_SQL.RETURN_RESULT(v_ref_cursor)
END IF;
END;
Already tryed to convert the v_cursor into a sys_refcursor to be outputed by the DBMS_SQL package but didn't get anywhere.
Also i've tried to create a temporary table to hold the information, but then have a concurrency issue.
Any idea what i'm doing wrong, or any other possible solution to solve this issue?
Thanks in advance
Completely untested because I do not have the environment to test it but I would structure this quite differently, see below (I am assuming that the missing out in the specification is just a typo)
CREATE PROCEDURE SP_Testing (v_input IN VARCHAR2(50), v_OutID **out** NUMBER(1))
AS
v_ref_cursor SYS_REFCURSOR;
v_check NUMBER;
BEGIN
select count(1)
into v_check
from dummy_table dt
WHERE v_dummy_col3 = v_input
-- condition that need to know the nr of records of the select
IF v_check = 0 THEN
v_OutID := 0;
ELSE
v_OutID := 1;
OPEN v_ref_cursor FOR
SELECT dt.v_dummy_col1,
dt.v_dummy_col2
FROM dummy_table dt
WHERE v_dummy_col3 = v_input
-- return dataset to .net application
DBMS_SQL.RETURN_RESULT(v_ref_cursor)
END IF;
END;

PL/SQL Unable to get return value of a function when called through trigger - Oracle

I am calling a function in oracle in an after update trigger. The Function is returning a value that is equated to perform a select and an insert operation.
The issue is when I am calling this function in the trigger it is getting terminated, that is it is not performing the corresponding insert operation. But the function is working fine when I execute it by itself. Also, if the trigger is run by removing the condition which is returned by the function, it is getting executed as expected.
Function:
CREATE OR REPLACE FUNCTION VERIFY_FINAL
(case_id IN number)
RETURN varchar2
IS
is_marked_final varchar2(4);
loop_count number(2);
cursor c1 is
SELECT sub_case_status from
cdm_master_sub_case
where master_id = (case_id);
BEGIN
is_marked_final := 'Y';
loop_count := 0;
FOR rec in c1
LOOP
IF (rec.sub_case_status = '1') THEN
is_marked_final := 'Y';
ELSIF (rec.sub_case_status = '2') THEN
is_marked_final := 'Y';
ELSE
loop_count := loop_count + 1;
END if;
END LOOP;
IF (loop_count > 0) THEN
is_marked_final := 'N';
END if;
RETURN is_marked_final;
END;
Trigger:
CREATE OR REPLACE TRIGGER CDM_MASTER_SUB_CASE_TRIGGER
AFTER UPDATE
on CDM_MASTER_SUB_CASE
FOR EACH ROW
DECLARE
check_var varchar2(4);
unique_id varchar2(100);
transaction_id number(10);
BEGIN
transaction_id := :new.MASTER_ID;
check_var := VERIFY_FINAL(transaction_id);
IF (check_var = 'Y') THEN
select UNIQUE_CUST_ID
INTO unique_id
from ASM355.cdm_matches
where MASTER_ID = :new.MASTER_ID
and rownum = 1;
INSERT INTO tracking_final_cases (MASTER_ID,unique_cust)
values (:new.master_id,unique_id);
END if;
END;
I would appreciate it if anyone can point me in the right direction.
1.) As tmrozek points out a return of 'N' will not do the associated insert. I might suggest having an ELSE to that IF that does something to indicate if that is what is happening.
2.) I would also point out that your SELECT INTO, if it does not find a corresponding value, would cause issues. You might want to do something to ensure that this trigger is failsafe, or have you considered what you want the code to do if that situation occurs? (Error out? Insert a null unique_id?)
3.) If you are looking at the results from a different session, bear in mind that the inserted tracking_final_cases will not be visible until you commit your changes in the session that called the trigger.
I don't know your table data but it is possible to your function to return 'N' so it wouldn't meet your trigger condition (check_var = 'Y').
If you run command like that:
update CDM_MASTER_SUB_CASE
set sub_case_status = 3;
you will probably get your problem.
Thanks guys for the time, it got resolved. I was querying a select statement in the function body over a table on which the corresponding trigger was created.

Oracle PL/SQL function: if parameter not in table column => continue program

Please see my code below. If the parameter p_cust_id is not in the column cust_id I want "0" to be printed out (which means not logged in). If it is in cust_id I want oracle to continue the second part of the code (the part below the empty row).
I have tried to solve this by inserting the values of column cust_id in a cursor and then inserting it in the variable v_cust_id. Perhaps this results in unnecessarily much code?
My problem is that the program does not seem to run the second part even if p_cust_id is in cust_id. It just prints out "0" even though the customer ID and the password are correct.
Before I added the cursor the program worked as it was supposed to, unless the parameter p_cust_id didn't match any value in the cust_id column. If this was the case nothing was printed out.
create or replace function log_in(
p_cust_id in customer.cust_id%type,
p_passwd in customer.passwd%type)
return varchar2
as
cursor c_cust_id is select cust_id from customer;
v_cust_id customer.cust_id%type;
v_passwd customer.passwd%type;
v_logged_in number(1);
v_not_logged_in number(1);
begin
v_logged_in := 1;
v_not_logged_in := 0;
if not c_cust_id%isopen then
open c_cust_id;
end if;
loop
fetch c_cust_id
into v_cust_id;
exit when c_cust_id%notfound;
end loop;
if p_cust_id not in(v_cust_id) then
return v_not_logged_in;
end if;
close c_cust_id;
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
if v_passwd = p_passwd then
return v_logged_in;
else
return v_not_logged_in;
end if;
end;
I could see, you don't need a cursor at all, to check if the cust_id is in the table. Just search for the cust_id in the table, and attempt to fetch the password. If it exists, you get the value, and NO_DATA_FOUND exception otherwise which means not logged in.
BEGIN
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return v_not_logged_in;
END;
Full code will be:
create or replace function log_in(
p_cust_id in customer.cust_id%type,
p_passwd in customer.passwd%type)
return varchar2
as
v_cust_id customer.cust_id%type;
v_passwd customer.passwd%type;
v_logged_in number(1);
v_not_logged_in number(1);
begin
v_logged_in := 1;
v_not_logged_in := 0;
BEGIN
select passwd
into v_passwd
from customer
where cust_id = p_cust_id;
EXCEPTION
WHEN NO_DATA_FOUND THEN
return v_not_logged_in;
END;
if v_passwd = p_passwd then
return v_logged_in;
else
return v_not_logged_in;
end if;
end;

Resources