Check record exist before update - oracle

I want to update a table but I want to check if the record exist. If not then throw an exception. In the C# application I pass the parameters and execute the command by the following.
procedure usp_update_example
(
p_id in mydb.member.idn_member%type,
p_idn_person in mydb.member.idn_person%type,
p_ind_rep in mydb.member.ind_rep%type
)
as
v_exist pls_integer := 0;
v_step varchar2(250);
v_exception_not_exist exception;
begin
v_step := 'Check for record ' || p_id;
select count(1)
into v_exist
from mydb.member
where idn_member = p_id;
if v_exist = 0 then
raise v_exception_not_exist;
end if;
if (v_exist > 0) then
v_step := 'Update table :' || p_id;
update mydb.member
set
idn_person = p_idn_person,
ind_rep = p_ind_rep
where idn_member = p_id;
end if;
exception
when v_exception_not_exist then
Raise_application_error(-20001, 'Not exist');
end usp_update_example;
However even my condition is right, I do have the record existing in the table. I always get Not exist exception. If I don't use if v_exist = 0 and use WHEN NO_DATA_FOUND THEN. Then everything is fine.
I am not sure where is wrong.

Your code seems to be fine. Looks like this issue is related to some uncommitted data - you see the record in the session where you inserted it and you don't see it in C# session since the record is not committed yet. Hence, C# session generates exception.
What I would suggest re the procedure code is to make it more compact.
Something like the following:
...
begin
update mydb.member
set idn_person = p_idn_person,
ind_rep = p_ind_rep
where idn_member = p_id;
if SQL%ROWCOUNT = 0 then
raise_application_error(-20001,'Not exist');
end if;
end;

Related

Calling Cursor Value into Exception

I have a cursor as part of a package, which compares the counts of 2 tables. If the counts match, rest of the package executes. But if it fails, it should update the counts in a log table.
The cursor code is
CURSOR C_CNT IS
SELECT
lnd.sml_batchrun_id batch_id,
lnd.lnd_count,
dwh.dwh_count
FROM
(
SELECT
sml_batchrun_id,
COUNT(*) lnd_count
FROM
iva_landing.lnd_sml_t
GROUP BY
sml_batchrun_id
) lnd
LEFT JOIN (
SELECT
batchrun_id,
sent_records_count dwh_count,
dwh_sending_table
FROM
dwh.dwh_idh_to_iva_metadata_t
) dwh ON dwh.batchrun_id = lnd.sml_batchrun_id
WHERE dwh.dwh_sending_table = 'DWH_SML_T'
ORDER BY
1 DESC;
The comparison code is:
FOR L_COUNT IN C_CNT LOOP --0001,0002
IF L_COUNT.lnd_count = L_COUNT.dwh_count THEN
UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
idh.RECEIVED_DATE = SYSDATE,
idh.RECEIVED_RECORDS_COUNT = L_COUNT.lnd_count,
idh.status = 'Verified'
WHERE L_COUNT.batch_id = idh.batchrun_id
AND idh.dwh_sending_table = 'DWH_SML_T';
COMMIT;
ELSE
RAISE EXCPT_SML_MISSDATA; -- Throw error and exit process
END IF;
END LOOP;
Now, in the Exception Handling part, I want to display the counts in the error column of the log table
logger.log_error('IVA-MSG 200-010 - COUNT MISMATCH! - Aborting', p_log_id=>l_job_log.log_id);
l_job_log.end_date := systimestamp;
l_job_log.error_mesg := cur_cnt.dwh_count||' '|| cur_cnt.lnd_count;
l_job_log.status := iva_log.iva_job_log_pck.c_str_statusfailed;
iva_log.iva_job_log_pck.change_joblog_prc(pi_rec_joblog => l_job_log);
RAISE;
Here, cur_cnt is a variable defined as cur_cnt c_cnt%rowtype;
and l_job_log as l_job_log iva_log.iva_job_log_t%rowtype;
where iva_job_log_t is the log table name.
But after triggering the package the count is not visible in the error column. Also, if I put something in single quotes for the iva_job_log_t then it gets displayed in the log table.
Please suggest how to display the counts from the cursor.
Thanks
If you are still doing
FOR L_COUNT IN C_CNT LOOP
then your cur_cnt variable is never going to be populated; it will be the empty record it was declared as, so referring to any of its fields will always give you null.
You can just refer to the l_count values in the error log:
l_job_log.error_mesg := l_count.dwh_count ||' '|| l_count.lnd_count;
... as you do elsewhere inside the loop.
If the exception handler is currently later in the process, so l_count is out of scope (as the re-raise possibly suggests) then you could move it so it's within the else instead of being separated:
FOR L_COUNT IN C_CNT LOOP --0001,0002
IF L_COUNT.lnd_count = L_COUNT.dwh_count THEN
UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
idh.RECEIVED_DATE = SYSDATE,
idh.RECEIVED_RECORDS_COUNT = L_COUNT.lnd_count,
idh.status = 'Verified'
WHERE L_COUNT.batch_id = idh.batchrun_id
AND idh.dwh_sending_table = 'DWH_SML_T';
COMMIT;
ELSE
logger.log_error('IVA-MSG 200-010 - COUNT MISMATCH! - Aborting', p_log_id=>l_job_log.log_id);
l_job_log.end_date := systimestamp;
l_job_log.error_mesg := l_count.dwh_count||' '|| l_count.lnd_count;
l_job_log.status := iva_log.iva_job_log_pck.c_str_statusfailed;
iva_log.iva_job_log_pck.change_joblog_prc(pi_rec_joblog => l_job_log);
RAISE EXCPT_SML_MISSDATA; -- Throw error and exit process
END IF;
END LOOP;
Otherwise you would have to change the cursor loop handling to fetch into the variable, refer to that within the loop instead, and rely on that having the right values later:
OPEN C_CNT
LOOP
FETCH C_CNT INTO CUR_CNT;
EXIT WHEN C_CNT%NOTFOUND;
IF CUR_CNT.lnd_count = CUR_CNT.dwh_count THEN
UPDATE DWH.DWH_IDH_TO_IVA_METADATA_T idh
SET idh.IVA_RECEIVING_TABLE = 'LND_SML_T',
idh.RECEIVED_DATE = SYSDATE,
idh.RECEIVED_RECORDS_COUNT = CUR_CNT.lnd_count,
idh.status = 'Verified'
WHERE CUR_CNT.batch_id = idh.batchrun_id
AND idh.dwh_sending_table = 'DWH_SML_T';
COMMIT;
ELSE
RAISE EXCPT_SML_MISSDATA; -- Throw error and exit process
END IF;
END LOOP;
Your later exception handler should then work as it is.

NO DATA FOUND oracle using cursor

I have been searching online using different solution suggestion to handle no data in this code but to no avail. how can I handle the exception if no data is found. How can I solve this problem. I am not an expert in oracle though!
DECLARE
nCheckOption INT;
no_data_found EXCEPTION;
CURSOR TYPE_cursor IS
SELECT
D_NAL_REF.TRANS
, D_NAL_REF.INJ
, D_NAL_REF.REF
FROM D_NAL_REF D_NAL_REF
WHERE D_NAL_REF.REF IN
(SELECT AG_REF.REF
FROM AG_REF A_REF
WHERE A_REF.DESCEND_REF = 10
);
BEGIN
FOR rec IN TYPE_cursor
LOOP
nCheckOption := 0;
SELECT 1
INTO nCheckOption
FROM PERSON_TYPE WHERE TRANS = rec.TRANS AND INJ = rec.INJ;
IF nCheckOption = 1 THEN
UPDATE PERSON_TYPE
SET PERSON_TYPE.TYPE = rec.REF
WHERE TRANS = rec.TRANS
AND PERSON_TYPE.INJ = rec.INJ;
END IF;
EXCEPTION
WHEN no_data_found
THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END LOOP;
END;
/
Rewrite your code to eliminate the inner SELECT, which is the only place in your code where I can see that a NO_DATA_FOUND exception could possibly be raised:
BEGIN
FOR rec IN (SELECT d.TRANS,
d.INJ,
d.REF
FROM D_NAL_REF d
WHERE d.REF IN (SELECT a.REF
FROM AG_REF a
WHERE a.DESCEND_REF = 10) AND
(d.TRANS, d.INJ) IN (SELECT DISTINCT TRANS, INJ
FROM PERSON_TYPE))
LOOP
UPDATE PERSON_TYPE
SET TYPE = rec.REF
WHERE TRANS = rec.TRANS AND
INJ = rec.INJ;
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE ('Trapped the error!?');
END;
I think you need to find if cursor contains any record or not. If cursor is empty then it must return that error message written in exception block.
Or you want to print error message if update statement do not find any record to update.
Here is the pseudo code.
Declare
ncheckoption number := 0;
Cursor type_cursor is ....
Begin
For rec in type_cursor loop
ncheckoption := ncheckoption + 1;
Update ...
If sql%rowcount = 0 then
Dbms_output.put_line('error message, if you want here in case no record found in table to update');
-- loop will continue
-- if you want loop to break then issue exit statement here
End if;
End loop;
If ncheckoption = 0 then
Dbms_output.put_line('error message you want to print in case cursor is empty');
End if;
End;
/
Cheers!!

Check ID Exist and delete record in PL SQL

What I have to do is, whenever a STORE_CODE is entered it will check in the db and delete the store code. SO for that, I have written a procedure which is as below
PROCEDURE DELETE_STORE_INFO
(
P_STORE_CODE IN NVARCHAR2
)
AS
BEGIN
UPDATE TBL_RRSOC_STORE_INFO set ISACTIVE = 'N' where STORE_CODE = P_STORE_CODE;
END DELETE_STORE_INFO;
But here what missing is
what if the user enter the wrong store_code and does the operation so what it will do. how to check with that part ?
I guess something for COUNT wont work at this stage. Kindly suggest
You want to use SQL%ROWCOUNT to find out how many rows were affected by the previous SQL statement:
PROCEDURE DELETE_STORE_INFO
(
P_STORE_CODE IN NVARCHAR2
)
AS
BEGIN
UPDATE TBL_RRSOC_STORE_INFO
SET ISACTIVE = 'N'
WHERE STORE_CODE = P_STORE_CODE;
IF SQL%ROWCOUNT = 0 THEN
-- DBMS_OUTPUT.PUT_LINE( 'Store code does not exist.' );
RAISE_APPLICATION_ERROR( -20000, 'Store code does not exist.' );
END IF;
END DELETE_STORE_INFO;
/
You can use DBMS_OUTPUT.PUT_LINE( string ) to output to the SQL console (if you are calling this from an external language like PHP or Java then you will not see the output and you may not see it in the console if you have SET SERVEROUTPUT OFF).
You could also use RAISE_APPLICATION_ERROR( error_code, error_message ) to raise an exception if something invalid happens.
Alternatively you could return a status in an OUT parameter:
PROCEDURE DELETE_STORE_INFO
(
P_STORE_CODE IN NVARCHAR2,
O_STATUS OUT NUMBER
)
AS
BEGIN
UPDATE TBL_RRSOC_STORE_INFO
SET ISACTIVE = 'N'
WHERE STORE_CODE = P_STORE_CODE;
IF SQL%ROWCOUNT = 0 THEN
o_status := 0;
ELSE
o_status := 1;
END IF;
END DELETE_STORE_INFO;
/
Generally contract for your procedure is: caller gives some store_code and procedure guarantee that there is no active store with such code. What if caller gives the wrong store_code? It means there is no such store, so contract is accomplished. You should do nothing, no more :)
But if you wish to check whether update found the record or not, you can add something like
if sql%notfound then
dbms_output.put_line('There is no such store!');
end if;
immediately after update statement.
Especially for MT: just check simple script
create table t$(id integer);
insert into t$ values(1);
set serveroutput on
begin
update t$ set id = 2 where id = 1;
if sql%notfound
then dbms_output.put_line('#1: not found');
else dbms_output.put_line('#1: found');
end if;
update t$ set id = 4 where id = 3;
if sql%found then
dbms_output.put_line('#2: found');
else dbms_output.put_line('#2: not found');
end if;
end;
/
drop table t$;
My results are
Connected to Oracle Database 12c Enterprise Edition Release 12.1.0.2.0
#1: found
#2: not found
PL/SQL procedure successfully completed
There are something missunderstand in your request: you said you want to delete it but in the code, you just updated the store as incative.
Here is the proceure with both situation. You choose the right one:
CREATE OR REPLACE PROCEDURE DELETE_STORE_INFO (P_STORE_CODE IN NVARCHAR2) AS
n_count number;
BEGIN
select count(1) INTO n_count from TBL_RRSOC_STORE_INFO where STORE_CODE = p_store_code;
if n_count > 0 then
UPDATE TBL_RRSOC_STORE_INFO set ISACTIVE = 'N' where STORE_CODE = P_STORE_CODE;
-- or for deletion
-- DELETE TBL_RRSOC_STORE_INFO set ISACTIVE = 'N' where STORE_CODE = P_STORE_CODE;
else
DBMS_OUTPUT.PUT_LINE('the required store was not found');
end if;
END DELETE_STORE_INFO;

ORA-01007 "variable not in select list" from dbms_sql.column_value call

I am trying to use dynamic SQL to sample all the data in a schema with a pattern:
DECLARE
xsql varchar2(5000);
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
varvar varchar2(500);
PROCEDURE print_rec(rec in DBMS_SQL.DESC_REC) IS
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
DBMS_OUTPUT.NEW_LINE;
DBMS_OUTPUT.PUT_LINE('col_type = '
|| rec.col_type);
DBMS_OUTPUT.PUT_LINE('col_maxlen = '
|| rec.col_max_len);
DBMS_OUTPUT.PUT_LINE('col_name = '
|| rec.col_name);
DBMS_OUTPUT.PUT_LINE('col_name_len = '
|| rec.col_name_len);
DBMS_OUTPUT.PUT_LINE('col_schema_name = '
|| rec.col_schema_name);
DBMS_OUTPUT.PUT_LINE('col_schema_name_len = '
|| rec.col_schema_name_len);
DBMS_OUTPUT.PUT_LINE('col_precision = '
|| rec.col_precision);
DBMS_OUTPUT.PUT_LINE('col_scale = '
|| rec.col_scale);
DBMS_OUTPUT.PUT('col_null_ok = ');
IF (rec.col_null_ok) THEN
DBMS_OUTPUT.PUT_LINE('true');
ELSE
DBMS_OUTPUT.PUT_LINE('false');
END IF;
END;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
xsql:='
WITH got_r_num AS
(
SELECT e.* -- or whatever columns you want
, ROW_NUMBER () OVER (ORDER BY dbms_random.value) AS r_num
FROM dba_tab_columns e
)
SELECT * -- or list all columns except r_num
FROM got_r_num
WHERE r_num <= 10';
DBMS_SQL.PARSE(c, xsql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
LOOP
IF DBMS_SQL.FETCH_ROWS(c)>0 THEN
NULL;
-- get column values of the row
DBMS_SQL.COLUMN_VALUE(c, 2, varvar);
--dbms_output.put_line('varvar=');
--DBMS_SQL.COLUMN_VALUE(source_cursor, 2, name_var);
--DBMS_SQL.COLUMN_VALUE(source_cursor, 3, birthdate_var);
-- Bind the row into the cursor that inserts into the destination table. You
-- could alter this example to require the use of dynamic SQL by inserting an
-- if condition before the bind.
--DBMS_SQL.BIND_VARIABLE(destination_cursor, ':id_bind', id_var);
--DBMS_SQL.BIND_VARIABLE(destination_cursor, ':name_bind', name_var);
--DBMS_SQL.BIND_VARIABLE(destination_cursor, ':birthdate_bind',
--birthdate_var);
--ignore := DBMS_SQL.EXECUTE(destination_cursor);
--ELSE
-- No more rows to copy:
--EXIT;
END IF;
END LOOP;
--EXIT WHEN d != 10;
--END LOOP;
col_num := rec_tab.first;
IF (col_num IS NOT NULL) THEN
LOOP
print_rec(rec_tab(col_num));
col_num := rec_tab.next(col_num);
EXIT WHEN (col_num IS NULL);
END LOOP;
END IF;
DBMS_SQL.CLOSE_CURSOR(c);
END;
/
When I run that it gives me this error from the line with the dbms_sql.column_value call:
ORA-01007: variable not in select list
If I comment out that dbms_sql.column_value call it still errors but now with:
ORA-01002: fetch out of sequence
What am I doing wrong?
You have two problems in the code you posted. Firstly you have skipped part of the execution flow because you haven't called the DEFINE_COLUMN procedure. That is what is causing the ORA-01007 error, as the dynamic SQL processing hasn't been told about the select list columns via that call. For your current code you only need to define column 2, but assuming you will actually want to refer to the others you can define them in a loop. To treat them all as string for display you could do:
...
DBMS_SQL.PARSE(c, xsql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR i IN 1..col_cnt
LOOP
-- dbms_output.put_line('col_name is ' || rec_tab(i).col_name);
DBMS_SQL.DEFINE_COLUMN(c, i, varvar, 500);
END LOOP;
LOOP
IF DBMS_SQL.FETCH_ROWS(c)>0 THEN
...
If you want to do anything that needs to treat the variables as the right types you could have a local variable of each type and use the data type from the rec_tab information you already have from describe_columns to use the appropriately typed variable for each column.
The second problem, which you were hitting when you commented the column_value call, is still there once that definbe issue has been fixed. Your loop doesn't ever exit, so after you fetch the last row from the cursor you do a further invalid fetch, which throws ORA-01002. You have the code to avoid that already but it's commented out:
...
LOOP
IF DBMS_SQL.FETCH_ROWS(c)>0 THEN
-- get column values of the row
DBMS_SQL.COLUMN_VALUE(c, 2, varvar);
...
ELSE
-- No more rows to copy:
EXIT;
END IF;
END LOOP;
...
With those two changes your code runs, and dumps the view structure:
PL/SQL procedure successfully completed.
col_type = 1
col_maxlen = 30
col_name = OWNER
col_name_len = 5
col_schema_name =
col_schema_name_len = 0
col_precision = 0
col_scale = 0
col_null_ok = false
col_type = 1
col_maxlen = 30
col_name = TABLE_NAME
...
To those who find this question when accessing Oracle through ODP.NET, as I did:
We started getting this error whenever we would add column to an existing table in our application. I'm not sure what all the conditions were to make it fail, but ours were:
Run a SELECT * FROM "table".
Include a ROWNUM restriction in the WHERE clause (WHERE ROWNUM < 10).
Run that through the ODP.NET dataReader.GetSchemaTable() call.
Running unrestricted queries or running queries directly on Oracle SQL Developer did not seem to cause the error.
I've hit some pretty weird stuff in the past with Oracle connection pooling, so I eventually thought that could be the problem. The solution was to restart the web service to force all the connections to be fully dropped and recreated.
The theory is that the ODP.NET connection from the connection pool still had no idea the column existed on the table, but the column was returned by the database.

ora-01422 error by a procedure

Below code throwing ORA-01422 error. As my code uses select ... into I come to know it is fetching more than one row from the table but how can I overcome this by eliminating select into statement. Here is the code:
PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN
Declare
M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
M_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
T_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
Begin
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name ;
Begin
Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions
Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
Inst_Cd = :Global.Company_Cd And
To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';
If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then
DECLARE
id FormModule;
BEGIN
id := Find_Form(M_Transaction_Name); --<Replace your form name>--
IF Id_Null(id) THEN
Call_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
ELSE
Go_Form(Id) ;
END IF ;
END ;
Elsif Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'OPEN_FORM' Then
Open_Form(:Global.Forms_Path||M_Transaction_Name||'.Fmx');
Elsif Transaction_Type = 'REPORT' And Upper(Form_Open_Type) = 'RUN_PRODUCT' Then
Declare
Pl_Id ParamList;
Begin
Pl_Id := Get_Parameter_List('tmpdata');
IF NOT Id_Null(Pl_Id) THEN
Destroy_Parameter_List( Pl_Id );
END IF;
Pl_Id := Create_Parameter_List('tmpdata');
ADD_Parameter(pl_id,'Inst_Cd',TEXT_PARAMETER,:GLOBAL.Company_Cd);
ADD_Parameter(pl_id,'Ac_Year_Cd',TEXT_PARAMETER,:GLOBAL.Ac_Year_Cd);
ADD_Parameter(Pl_Id,'INST_NAME',TEXT_PARAMETER, :Global.Company_name);
ADD_Parameter(Pl_Id,'ADDRESS',TEXT_PARAMETER, :Global.Address);
ADD_Parameter(pl_id,'FOOTER',TEXT_PARAMETER,:GLOBAL.Footer);
Run_Product(REPORTS,:Global.Reports_Path||M_Transaction_Name, SYNCHRONOUS, RUNTIME,
FILESYSTEM, Pl_Id, NULL);
End;
End If;
Exception
When No_Data_Found Then
Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
Raise Form_Trigger_Failure;
End;
Exception
When No_Data_Found Then
Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
End;
END;
How can I rewrite the code to resolve ORA-01422 error?
First, you need to change exception handling logic:
enclose in begin ... exception ... end only part that really can
through exception;
handle too_many_rows exception
.
PROCEDURE Call_Transaction ( Transaction_Name Varchar2, Transaction_Type Varchar2, Form_Open_Type Varchar2 ) IS
BEGIN
Declare
M_Transaction_Name U_Transaction_Master.Transaction_Name%Type := Upper(Transaction_Name);
M_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
T_Transaction_Cd U_Transaction_Master.Transaction_Cd%Type;
Begin
-- 1st select with error analysis
begin
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name ;
exception
when No_Data_Found then begin
Message('The Transaction Cd Not Exists In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
end;
when too_many_rows then begin
-- What really must be done in this case?
Message('There are too many Transaction Cd's with passed name In Transaction Master, Please Contact Administrator...');
Raise Form_Trigger_Failure;
end;
end;
-- 2nd select with error analysis
begin
Select Transaction_Cd Into T_Transaction_Cd From U_User_Wise_Transactions
Where Login_Cd = :Global.Login_Cd And Transaction_Cd = M_Transaction_Cd And
Inst_Cd = :Global.Company_Cd And
To_Char(Valid_Upto_Date,'DD-MM-YYYY') = '31-12-9999';
Exception
When No_Data_Found Then begin
Message('Sorry..., You Do Not Have Authorization For : '||M_Transaction_Cd||' Transaction Code...');
Raise Form_Trigger_Failure;
end;
When too_many_rows Then begin
-- What really must be done in this case?
Message('Sorry..., there are some misconfiguration in Authorization Settings For : '||M_Transaction_Cd||' Transaction Code. Please contact Administrator.');
Raise Form_Trigger_Failure;
end;
End;
If Transaction_Type = 'FORM' And Upper(Form_Open_Type) = 'CALL_FORM' Then
---[... all other code skipped ...]---
End If;
END;
After refactoring you need to answer a question about what really must be performed in situations when more than one row found and handle it according to nature of implemented task.
If you worried about method that you can use to detect presence of values and determine it's count then you may look at this question on StackOverflow.
In oracle, you can keep the select into statement and limit the number of rows using ROWNUM:
Select Transaction_Cd Into M_Transaction_Cd From U_Transaction_Master
Where Transaction_Name = M_Transaction_Name
and ROWNUM < 2;

Resources