After adding the ifclause for Art to a MasterReport to multiple the Netto total by -1 for get a -ve result in the credit invoice, I am getting a ; expected with the error indicator jumping to the procedure after it.
Image of Error Message
It's likely a very stupid error but I can't wrap my head around the problem at the moment. Commenting the new ifclause out will resolve the issue so it's something with that.
procedure FooterSR1OnBeforePrint(Sender: TfrxComponent);
begin
if ( <frxdsqryKopfdaten."MwStNichtAusweisbar"> = 0 ) then
mmoBrutto.Memo.Text := FormatFloat('#,##0.00', EndBrutto ) + ' ' + <frxdsqryKopfdaten."CurrencyString">
else
mmoBrutto.Memo.Text := FormatFloat('#,##0.00', EndNetto ) + ' ' + <frxdsqryKopfdaten."CurrencyString">;
end;
procedure Hauptkopf1OnBeforePrint(Sender: TfrxComponent);
begin
if (<frxdsqryArt."Art"> = 'Gutschrift') then
begin
EndNetto := EndNetto * (-1)
end else begin
EndNetto := EndNetto;
end;
end;
begin
mmoNetto.Memo.Text := FormatFloat('#,##0.00', EndNetto ) + ' ' + frxdsqryKopfdaten."CurrencyString">
end;
procedure BandBankOnBeforePrint(Sender: TfrxComponent);
begin
if <frxdsqryFirma."Bank1"> <> '' then
mmoBank.Visible := False
else
mmoBank.Visible := FALSE;
if <frxdsqryFirma."IBAN1"> <> '' then
begin
mmoIBAN.Visible := FALSE;
mmoBank.Visible := FALSE;
mmoBank.Height := 0
end else begin
mmoIBAN.Visible := FALSE;
mmoBank.Visible := FALSE;
end;
end;
This is wrong (4× begin, but only 3× end):
procedure Hauptkopf1OnBeforePrint(Sender: TfrxComponent);
begin
if (<frxdsqryArt."Art"> = 'Gutschrift') then
begin
EndNetto := EndNetto * (-1)
end else begin
EndNetto := EndNetto;
end;
end;
begin
mmoNetto.Memo.Text := FormatFloat('#,##0.00', EndNetto ) + ' ' + frxdsqryKopfdaten."CurrencyString">
end;
Your probably wanted this (but hard to say):
procedure Hauptkopf1OnBeforePrint(Sender: TfrxComponent);
begin
if (<frxdsqryArt."Art"> = 'Gutschrift') then
begin
EndNetto := EndNetto * (-1)
end else begin
EndNetto := EndNetto;
end;
end;
mmoNetto.Memo.Text := FormatFloat('#,##0.00', EndNetto ) + ' ' + frxdsqryKopfdaten."CurrencyString">
end;
Related
I'm trying to do a very simple thing: extract a date and do some controls on it.
Everything's fine but when I try to compile this error pops out and I really don't have a clue about how to solve it...
This is the code:
function get_crediti_formativi_biennio(p_userid varchar2,
p_prof_abil varchar2,
p_id_persona number,
p_tipo_formazione number,
p_anno_formazione varchar2,
p_flag_calcolo number,
p_crediti_totali out number)
return varchar2 is
v_count number;
v_anno varchar2;
v_biennio_from number;
v_biennio_to number;
l_err_msg varchar2(1024) := '+OK0000 Operazione effettuata con successo';
begin
v_count := null;
begin
select TO_CHAR(ap.valore)
into v_anno
from intc_attr_persone ap
where ap.id_attributo = 202
and ap.id = p_id_persona;
exception
when no_data_found then
v_anno := '';
end;
if v_anno >= 2015 and (mod(v_anno, 2) != 0) then
if (mod(p_anno_formazione, 2) = 0) then
v_biennio_from := p_anno_formazione;
v_biennio_to := p_anno_formazione + 1;
else
v_biennio_from := p_anno_formazione - 1;
v_biennio_to := p_anno_formazione;
end if;
else
if v_anno < 2015 or v_anno = '' or v_anno is null then
if (mod(p_anno_formazione, 2) = 0) then
v_biennio_from := p_anno_formazione - 1;
v_biennio_to := p_anno_formazione;
else
v_biennio_from := p_anno_formazione;
v_biennio_to := p_anno_formazione + 1;
end if;
end if;
end if;
The problem is on v_anno.....
Well I was writing a trigger and I wanted that the declared variable v_message to append every time the condition is met. So for example if the first two statements are met the v_message should be something like "Invalid account Invalid amount". I must also find a way to separate these two messages by a space if the v_message already contains some sort of an error message as it wont be readable if you had something like this "Invalid accountInvalid amount".
CREATE OR REPLACE TRIGGER checkPayments
BEFORE INSERT ON tbl_payments
FOR EACH ROW
DECLARE
v_message VARCHAR(100 CHAR);
v_is_valid CHAR(1) := 'N';
BEGIN
IF getActiveUser(getOrderUsername(:new.order_id)) = 0
THEN v_message := 'Invalid account';
ELSIF isValidAmount(:new.payment_amount) = 0
THEN v_message := 'Invalid amount';
ELSIF checkOrderExist(:new.order_id) = 0
THEN v_message := 'Invalid order ID';
ELSIF (getValidOrderPayments(:new.order_id) + :new.payment_amount ) > getOrderTotal(:new.order_id)
THEN v_message := 'Payment exceeds total';
ELSE v_message := 'OK' ;
v_is_valid := 'Y';
END IF;
:new.payment_id:= seq_payment_id.nextval;
:new.payment_date:= LOCALTIMESTAMP;
:new.payment_message := v_message;
:new.is_valid := v_is_valid;
END;
/
CREATE OR REPLACE TRIGGER checkPayments
BEFORE INSERT ON tbl_payments
FOR EACH ROW
DECLARE
v_message VARCHAR(100 CHAR);
v_is_valid CHAR(1) := 'N';
BEGIN
v_is_valid := 'Y';
IF getActiveUser(getOrderUsername(:new.order_id)) = 0
THEN v_message := 'Invalid account';
v_is_valid := 'N';
END IF;
IF isValidAmount(:new.payment_amount) = 0
THEN v_message := v_message || ' Invalid amount';
v_is_valid := 'N';
END IF;
IF checkOrderExist(:new.order_id) = 0
THEN v_message := v_message || ' Invalid order ID';
v_is_valid := 'N';
END IF;
IF (getValidOrderPayments(:new.order_id) + :new.payment_amount ) > getOrderTotal(:new.order_id)
THEN v_message := v_message || ' Payment exceeds total';
v_is_valid := 'N';
END IF;
IF v_is_valid = 'Y'
THEN v_message := 'OK' ;
END IF;
:new.payment_id:= seq_payment_id.nextval;
:new.payment_date:= LOCALTIMESTAMP;
:new.payment_message := trim(v_message);
:new.is_valid := v_is_valid;
END;
/
I am getting following error for the stored procedure and not able to understand the issue (must be from db side) While googling, I found similar issues but couldn't get the solution. Can any one help me please find the error in PROCEDURE ??
Error :-
18:58:50,281 ERROR [STDERR] java.sql.SQLException: ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'SP_DIST_RETAILER_REMAP'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Stored Prodedure(SP_DIST_RETAILER_REMAP) :-
CREATE OR REPLACE PROCEDURE SMAPRD02.SP_DIST_RETAILER_REMAP (
i_old_dist_code IN VARCHAR2,
i_new_dist_code IN VARCHAR2,
i_territory_remapping IN NUMBER,
i_remapping_reason IN VARCHAR2,
i_trans_doneby_rolename IN VARCHAR2,
i_trans_doneby_id IN NUMBER,
i_trans_dist_rolename IN VARCHAR2,
i_trans_ret_rolename IN VARCHAR2,
i_activity_type IN VARCHAR2,
i_ret_list IN V_ARRAY,
result OUT VARCHAR2,
i_o_query OUT VARCHAR2
)
AS
--i_ret_codes OUT VARCHAR2;
v_dist_count NUMBER;
v_ret_count NUMBER;
v_ret_codes VARCHAR2(10000) := '';
v_flag VARCHAR2(10) := 'true';
v_trans_id NUMBER;
v_query VARCHAR2(10000);
BEGIN
IF i_territory_remapping = 1 then
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code
from tblemployee emp where emp.empcode = i_old_dist_code) and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
ELSE
SELECT count(*) into v_dist_count FROM tblemployee where EMPCODE = i_new_dist_code and circle_code = (select emp.circle_code from tblemployee emp
where emp.empcode = i_old_dist_code) and cluster_code = (select emp.cluster_code from tblemployee emp where emp.empcode = i_old_dist_code)
and upper(user_type) like upper('%dist%') and upper(ACCESS_TO) in ('SALES','BOTH') and upper(stage) not in (upper('InActive'));
END IF;
IF v_dist_count =0 THEN
result := 'invalid_new_dist_code';
v_flag := 'false';
ELSIF v_dist_count = 1 THEN
SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and (upper(t.ACCESS_TO) = 'SALES' or upper(t.ACCESS_TO) = 'BOTH');
--SELECT count(*) into v_ret_count FROM tblretailer t where t.DIST_CODE = i_old_dist_code and upper(t.ACCESS_TO) = 'SALES' and upper(t.stage) in ('APPROVED','INACTIVE');
IF v_ret_count=i_ret_list.count THEN
IF i_territory_remapping = 1 THEN
result := 'no_ret_left';
v_flag := 'false';
END IF;
ELSE
IF i_territory_remapping != 1 THEN
result := 'ret_left';
v_flag := 'false';
END IF;
END IF;
END IF;
IF i_ret_list is null or i_ret_list.count = 0 THEN
result := 'empty retailers list';
v_flag := 'false';
END IF;
/*FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
IF v_ret_codes is null
THEN
v_ret_codes := i_ret_list(i);
ELSE
v_ret_codes := v_ret_codes||','||i_ret_list(i);
END IF;
END LOOP;
i_ret_codes := v_ret_codes;
v_flag := 'false';
result := 'success';*/
IF v_flag = 'true' THEN
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
IF v_ret_codes is null
THEN
v_ret_codes := ''''||i_ret_list(i)||'''';
ELSE
v_ret_codes := v_ret_codes||','''||i_ret_list(i)||'''';
END IF;
END LOOP;
--i_ret_codes := v_ret_codes;
--update tblretailer set dist_code=i_new_dist_code,DIST_ID=to_number(i_new_dist_code),cluster_code=(select cluster_code from tblemployee where empcode = i_new_dist_code),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in (v_ret_codes);
v_query := 'update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='''',FOS_CODE='''',DSR_ID='''',DSR_CODE='''',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||')';
execute immediate (v_query);
--i_query :='update tblretailer set dist_code='||i_new_dist_code||',DIST_ID=to_number('||i_new_dist_code||'),cluster_code=(select cluster_code from tblemployee where empcode = '||i_new_dist_code||'),FOSID='',FOS_CODE='',DSR_ID='',DSR_CODE='',LAST_UPDATED_DATE=sysdate where retcode in ('||v_ret_codes||');';
insert into TBL_TRANSFER_SUP_MASTER(MASTER_ID,TRANS_ID,TRANS_DONEBY_ROLENAME,TRANS_DONEBY_ID,TRANS_FROM_ROLENAME,TRANS_FROM,TRANS_TO_ROLENAME,TRANS_TO,ACTIVITY_CODE,TRANS_DATE,TRANSFER_REASON,LAST_UPDATED_DATE)
values(SUP_MASTER_TRANS_ID_SEQ.nextval,SUP_MASTER_TRANS_ID_SEQ.nextval,i_trans_doneby_rolename,i_trans_doneby_id,i_trans_dist_rolename,i_old_dist_code,i_trans_dist_rolename,i_new_dist_code,'101',sysdate,i_remapping_reason,sysdate) return TRANS_ID into v_trans_id;
FOR i IN i_ret_list.FIRST .. i_ret_list.LAST
LOOP
insert into TBL_TRANSFER_SUP_DTLS(DTLS_ID,TRANS_ID,TRANS_ON_ROLENAME,TRANS_ON_ID,LAST_UPDATED_DATE)
values(SUP_DTLS_ID_SEQ.nextval,v_trans_id,i_trans_ret_rolename,i_ret_list(i),sysdate);
END LOOP;
IF SQL%ROWCOUNT>0 THEN
result := 'success';
ELSE
result := 'failure';
END IF;
--update tblstock set NEW_DIST_CODE_REMAP=i_new_dist_code,REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE=i_old_dist_code or NEW_DIST_CODE_REMAP=i_old_dist_code) and RET_CODE in (v_ret_codes);
v_query := 'update tblstock set NEW_DIST_CODE_REMAP='||i_new_dist_code||',REMAP_DATE=sysdate,LAST_UPDATED_DATE=sysdate where (DIST_CODE='||i_old_dist_code||' or NEW_DIST_CODE_REMAP='||i_old_dist_code||') and RET_CODE in ('||v_ret_codes||')';
execute immediate (v_query);
i_o_query := v_query;
insert all into TBL_ACTIVITY_LOG (LOG_ID,TRANS_ID,ACTIVITY_DONEBY_ROLENAME,ACTIVITY_DONEBY_ID,ACTIVITY_REFERENCE_ID,ACTIVITY_CODE,ACTIVITY_DATE)
values(ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,ACTIVITY_LOG_TRANS_ID_SEQ.NEXTVAL,i_trans_doneby_rolename,i_trans_doneby_id,v_trans_id,
act_code,sysdate) select log_config.ACTIVITY_CODE act_code from TBL_ACTIVITY_LOG_CONFIG log_config
where upper(log_config.ACTIVITY_TYPE)= upper(i_activity_type);
END IF;
END;
/
Java Code :-
try{
if(ret_list.size()>0)
ret_code = ret_list.toArray();
con = ConnectionManager.getDirectConnection();
ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor(PropertyLoader.RET_SECONDARY_V_ARRAY,con);
ARRAY array_to_pass = new ARRAY( descriptor,con, ret_code );
cstmt = con.prepareCall("{ call SP_DIST_RETAILER_REMAP(?,?,?,?,?,?,?,?,?,?,?,?)}");
cstmt.setString(1,old_dist_code.trim());
cstmt.setString(2,new_dist_code.trim());
if(territory_remapping)
cstmt.setInt(3,1);
else
cstmt.setInt(3,2);
cstmt.setString(4,remapping_reason);
cstmt.setString(5,userVO.getRolename().trim());
cstmt.setInt(6,userVO.getEmpid());
cstmt.setString(7,PropertyLoader.DISTRIBUOTR_ROLENAME);
cstmt.setString(8,PropertyLoader.RETAILER_ROLENAME);
cstmt.setString(9,PropertyLoader.ACTIVITY_TYPES_RETAILER_REMAPPING);
cstmt.setArray(10,array_to_pass);
cstmt.registerOutParameter(11,Types.VARCHAR);
cstmt.registerOutParameter(12,Types.VARCHAR);
/*cstmt.registerOutParameter(13,Types.VARCHAR);*/
cstmt.execute();
status = cstmt.getString(11);
System.out.println("Remap Update Query "+cstmt.getString(12));
//System.out.println(cstmt.getString(13));
}
If the value stored in PropertyLoader.RET_SECONDARY_V_ARRAY is not "V_ARRAY", then you are using different types; even if they are declared identically (e.g. both are table of number) this will not work.
You're hitting this data type compatibility restriction:
You can assign a collection to a collection variable only if they have
the same data type. Having the same element type is not enough.
You're trying to call the procedure with a parameter that is a different type to the one it's expecting, which is what the error message is telling you.
The procedure which you are using is should be properly declared in the place which you are using it. For an example if it is under a user and in a package then it should be in that order. The username, package and procedurename.
I am trying to create a CRUD matrix for my function from a source code of that function, so I created a procedure that will read a source code.
create or replace procedure test_
IS
CURSOR c_text is
SELECT USER_SOURCE.TEXT
FROM USER_SOURCE
WHERE USER_SOURCE.name='TEST_FUNCTION'
AND USER_SOURCE.type='FUNCTION';
order by line;
v_single_text varchar2(4000);
v_tmp_text varchar2(10000) := ' ';
begin
open c_text;
loop
fetch c_text into v_single_text;
exit when c_text%notfound;
v_tmp_text := v_tmp_text|| chr(10) || rtrim(v_single_text);
dbms_output.put_line(v_single_text);
end loop;
close c_text;
end test_;
And that works very good for me, I get the source code of my desired function. It's a very simple function and I use this to learn PL/SQL. Output of that procedure look's like this.
function test_funkction Return varchar2
IS
kpp_value varchar2(20);
begin
select KPP
into kpp_value
from CUSTOMER
where CUSTOMER_ID = 200713;
dbms_output.put_line (kpp_value);
Return kpp_value;
end test_function;
Now, how to parse the string I've got in the output to get a desired result, my result should be like this
==TABLE_NAME==========OPERATIONS==
CUSTOMER - R - -
==================================
Now I have managed to do it.
But it will only work with my simple function, now I want to make a procedure that will work with any function.
Source code below.
create or replace procedure test_
IS
v_string_fnc varchar2(10000) := UPPER('function test_function
Return varchar2
IS
kpp_value varchar2(20);
begin
select KPP into kpp_value from CUSTOMER where CUSTOMER_ID = 200713;
dbms_output.put_line (kpp_value);
Return kpp_value;
end test_function;');
v_check PLS_INTEGER;
CURSOR c_text is
SELECT USER_SOURCE.TEXT
FROM USER_SOURCE
WHERE USER_SOURCE.name = 'TEST_FUNCTION'
AND USER_SOURCE.type = 'FUNCTION'
order by line;
v_single_text varchar2(4000);
v_tmp_text varchar2(10000) := ' ';
/*v_string varchar2(10000);*/
insert_flag char := '-';
read_flag char := '-';
update_flag char := '-';
delete_flag char := '-';
empty_space char(34) := ' ';
underline char(42) := '==========================================';
/*v_txt varchar2(10000) := ' ';*/
result_table varchar2(1000) := '/';
begin
open c_text;
loop
fetch c_text
into v_single_text;
exit when c_text%notfound;
v_tmp_text := v_tmp_text || chr(10) || rtrim(v_single_text);
/* print source code*/
/*dbms_output.put_line(v_single_text);*/
end loop;
close c_text;
/*DELETE SEARCH*/
v_check := instr(v_string_fnc, 'DELETE ');
if v_check < 1 then
dbms_output.put_line('THERE IS NO DELETE COMMAND');
else
dbms_output.put_line('THERE IS A DELETE COMMAND');
delete_flag := 'D';
v_check := instr(v_string_fnc, 'FROM ');
v_check := v_check + 5;
result_table := substr(v_string_fnc, v_check);
result_table := substr(result_table, 0, instr(result_table, ' '));
dbms_output.put_line('TABLE AFFECTED BY DELETE: ' || result_table);
end if;
/*SELECT SEARCH*/
v_check := instr(v_string_fnc, 'SELECT ');
if v_check < 1 then
dbms_output.put_line('THERE IS NO READ COMMAND');
else
dbms_output.put_line('THERE IS A READ COMMAND');
read_flag := 'R';
v_check := instr(v_string_fnc, 'FROM ');
v_check := v_check + 5;
result_table := substr(v_string_fnc, v_check);
result_table := substr(result_table, 0, instr(result_table, ' '));
dbms_output.put_line('TABLE AFFECTED BY READ: ' || result_table);
end if;
/*UPDATE SEARCH*/
v_check := instr(v_string_fnc, 'UPDATE ');
if v_check < 1 then
dbms_output.put_line('THERE IS NO UPDATE COMMAND');
else
dbms_output.put_line('THERE IS A UPDATE COMMAND');
update_flag := 'U';
v_check := instr(v_string_fnc, 'FROM ');
v_check := v_check + 5;
result_table := substr(v_string_fnc, v_check);
result_table := substr(result_table, 0, instr(result_table, ' '));
dbms_output.put_line('TABLE AFFECTED BY UPDATE: ' || result_table);
end if;
/*INSERT SEARCH*/
v_check := instr(v_string_fnc, 'INSERT ');
if v_check < 1 then
dbms_output.put_line('THERE IS NO CREATE COMMAND');
else
dbms_output.put_line('THERE IS A CREATE COMMAND');
insert_flag := 'C';
v_check := instr(v_string_fnc, 'FROM ');
v_check := v_check + 5;
result_table := substr(v_string_fnc, v_check);
result_table := substr(result_table, 0, instr(result_table, ' '));
dbms_output.put_line('TABLE AFFECTED BY CREATE: ' || result_table);
end if;
dbms_output.put_line(' ');
dbms_output.put_line('==========' || 'TABLE_NAME' || '==========' ||
'OPERATIONS' || '==');
dbms_output.put_line(empty_space || insert_flag || read_flag ||
update_flag || delete_flag);
dbms_output.put_line(underline);
end test_;
With that procedure I can extract and output my code, dbms needs a bit clean up but it will give the result I need.
Now a few questions, how to put a source code of my function to a variable that is not predefined, here is v_string_fnc but it needs to be predefined to work.
And how to link a certain operation with the table, here in my example is easy, one SELECT and keyword FROM that gives me a name of table.
Struggling continues
The bigger part it's done, just a tuning after this.
v_check := instr2(v_string_fnc, 'DROP ');
if v_check > 0 then
delete_flag := 'D';
v_check := instr2(v_string_fnc, 'TABLE ', v_check);
v_check := v_check + 6;
result_table := substr(v_string_fnc, v_check);
rest_string := result_table;
result_table := substr(result_table, 0, instr(result_table, ' '));
result_table := rtrim(result_table);
result_table := rtrim(result_table, ';');
merge into result_set
using dual
on (tables_used = result_table)
when matched then
update set drop_operation = delete_flag
when not matched then
insert
(tables_used, drop_operation)
values
(result_table, delete_flag);
while v_check > 0 loop
v_check := instr2(rest_string, 'DROP ');
if v_check > 0 then
delete_flag := 'D';
v_check := instr2(rest_string, 'TABLE ', v_check);
v_check := v_check + 6;
result_table := substr(rest_string, v_check);
rest_string := result_table;
result_table := substr(result_table, 0, instr(result_table, ' '));
result_table := rtrim(result_table);
result_table := rtrim(result_table, ';');
merge into result_set
using dual
on (tables_used = result_table)
when matched then
update set drop_operation = delete_flag
when not matched then
insert
(tables_used, drop_operation)
values
(result_table, delete_flag);
end if;
end loop;
end if;
Here is the script that i wrote and it has weird syntax error at EXCEPTION block. If i remove exception block the script compiles properly. but no sooner i write it back it gives me error
Error(58,11): PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following: ( begin case declare else elsif end exit for goto if loop mod null pragma raise return select update while with <an identifier> <a double-quoted delimited-identifier> <a bind variable> << continue close current delete fetch lock insert open rollback savepoint set sql execute commit forall merge pipe purge
Here is the script
LOOP
BEGIN
SAVEPOINT check_point;
EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
DBMS_SQL.COLUMN_VALUE (cursor_handle, 1, cc , col_err, actual_len);
DBMS_SQL.COLUMN_VALUE (cursor_handle, 2, di, col_err, actual_len);
IF INSTR (cc, '_') <> 0 THEN
cc := Trim (cc);
cc := Upper(cc);
cc := substr(cc,4,2);
EXECUTE IMMEDIATE 'UPDATE ' || dest || ' SET cc = :v1 WHERE di = :v2'
USING cc, di;
if SQL%ROWCOUNT > 0 THEN
inserts := inserts + 1;
counter := counter + 1;
IF counter > 500 THEN
counter := 0;
COMMIT;
END IF;
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dups := dups+1;
ROLLBACK TO check_point;
WHEN VALUE_ERROR THEN
valerr := valerr +1;
ROLLBACK TO check_point;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
otherexc := otherexc +1;
IF otherexc > 50 THEN
EXIT;
END IF;
ROLLBACK TO check_point;
END IF;
END;
END LOOP;
I know its very annoying to ask such kind a question but i am unable to figure out what error is that. I am lehman at Pl/SQL.
The error appears to be that your EXCEPTION clause is inside the IF INSTR (cc, '_') <> 0 IF statements but you appear to want to match the EXCEPTION to the BEGIN statement at the top of your loop. I believe that you want to move the END IF; for the IF INSTR (cc, '_') <> 0 before the EXCEPTION as I do here
LOOP
BEGIN
SAVEPOINT check_point;
EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
DBMS_SQL.COLUMN_VALUE (cursor_handle, 1, cc , col_err, actual_len);
DBMS_SQL.COLUMN_VALUE (cursor_handle, 2, di, col_err, actual_len);
IF INSTR (cc, '_') <> 0 THEN
cc := Trim (cc);
cc := Upper(cc);
cc := substr(cc,4,2);
EXECUTE IMMEDIATE 'UPDATE ' || dest || ' SET cc = :v1 WHERE di = :v2'
USING cc, di;
if SQL%ROWCOUNT > 0 THEN
inserts := inserts + 1;
counter := counter + 1;
IF counter > 500 THEN
counter := 0;
COMMIT;
END IF; -- IF counter > 500
END IF; -- IF SQL%ROWCOUNT > 0
END IF; -- INSTR (cc, '_') <> 0
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dups := dups+1;
ROLLBACK TO check_point;
WHEN VALUE_ERROR THEN
valerr := valerr +1;
ROLLBACK TO check_point;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
otherexc := otherexc +1;
IF otherexc > 50 THEN
EXIT;
END IF;
ROLLBACK TO check_point;
END;
END LOOP;
That being said, however, I would probably rewrite the code a bit. Committing every 500 rows is almost certainly an error. I'm very dubious of your WHEN OTHERS exception handler-- I would really think that you'd want to at least write the error to a table or populate a collection of errors rather than writing to the DBMS_OUTPUT buffer that may or may not ever be displayed.
LOOP
SAVEPOINT check_point;
EXIT WHEN DBMS_SQL.FETCH_ROWS (cursor_handle) = 0;
DBMS_SQL.COLUMN_VALUE (cursor_handle, 1, cc , col_err, actual_len);
DBMS_SQL.COLUMN_VALUE (cursor_handle, 2, di, col_err, actual_len);
IF INSTR (cc, '_') <> 0 THEN
cc := Trim (cc);
cc := Upper(cc);
cc := substr(cc,4,2);
BEGIN
EXECUTE IMMEDIATE 'UPDATE ' || dest || ' SET cc = :v1 WHERE di = :v2'
USING cc, di;
if SQL%ROWCOUNT > 0 THEN
inserts := inserts + 1;
END IF;
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
dups := dups+1;
ROLLBACK TO check_point;
WHEN VALUE_ERROR THEN
valerr := valerr +1;
ROLLBACK TO check_point;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('errno: ' || TO_CHAR(SQLCODE) || ' Msg: ' || SQLERRM);
otherexc := otherexc +1;
IF otherexc > 50 THEN
EXIT;
END IF;
ROLLBACK TO check_point;
END;
END IF; -- INSTR (cc, '_') <> 0
END LOOP;