Set Variable value - oracle

I have declared the variable for v_error but when inside my begin I do set a number value for the variable I get a error under the equals 'Syntax Error'
Code Below:
DECLARE
v_error varchar(1);
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE :v_tab1';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -942 THEN
set #v_error = 0; — error here
DBMS_OUTPUT.put_line('This table does not exist!');
ELSE
RAISE;
DBMS_OUTPUT.put_line('Exception Occurred on table drop' );
v_error := '1';
END IF;
END;

Keeping aside the usage of :v_tab1, which strongly depends on the client/tool you use to run this code, you need to edit your syntax according to what you already do a few lines after:
DECLARE
v_error varchar(1);
BEGIN
EXECUTE IMMEDIATE 'TRUNCATE TABLE :v_tab1';
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE = -942 THEN
v_error := '0'; /* <------ like you do for v_error := '1'; */
DBMS_OUTPUT.put_line('This table does not exist!');
ELSE
RAISE;
DBMS_OUTPUT.put_line('Exception Occurred on table drop' );
v_error := '1';
END IF;
END;

Related

'PLS-00049: bad bind variable' when compiling function

I am getting error while I compile this function:
PLS-00049: bad bind variable 'RETURN_VALUE'
I need help with this please.
FUNCTION GECM_ROUND_FNC
(P_FIELD_VALUE IN NUMBER,
P_ORG_ID IN NUMBER)
RETURN VARCHAR2
IS
v_ret_val NUMBER := P_FIELD_VALUE;
V_OU_NAME hr_operating_units.name%type;
v_round_dec NUMBER;
BEGIN
BEGIN
SELECT NAME INTO V_OU_NAME
FROM HR_ALL_ORGANIZATION_UNITS
WHERE ORGANIZATION_ID = P_ORG_ID;
EXCEPTION WHEN OTHERS THEN
V_OU_NAME := '';
END;
--
IF V_OU_NAME IS NOT NULL AND NVL(GECM_ICP_PKG.gecm_get_process_value_fnc('GECM_ERP_VALIDATIONS',V_OU_NAME,'','',''),'N')='Y' THEN
BEGIN
IF NVL(GECM_ICP_PKG.GECM_GET_PARAMETER_VALUE_FNC('GECM_ERP_VALIDATIONS','DECIMAL_ROUNDING_INTERFACES',V_OU_NAME,'',''),0) = 'Y' THEN
BEGIN
SELECT NVL(GECM_ICP_PKG.GECM_GET_PARAMETER_VALUE_FNC('GECM_ERP_VALIDATIONS','DECIMAL_PLACE_LIMIT',V_OU_NAME,'',''),0)
INTO v_round_dec from dual;
EXCEPTION
WHEN OTHERS THEN
v_round_dec := 0;
END;
IF v_round_dec <> 0 THEN
v_ret_val:= TO_CHAR(ROUND(v_ret_val,v_round_dec));
ELSE
v_ret_val:=v_ret_val;
END IF;
END IF;
END;
END IF;
SELECT to_char(decode(sign(v_ret_val-1),-1,decode('0'||to_number(v_ret_val),'00','0','0'||to_number(v_ret_val)),v_ret_val)) INTO v_ret_val FROM DUAL;
:return_value := v_ret_val;
END;
Instead of
:return_value := v_ret_val;
use
return v_ret_val;

regex to remove commas between quotes in Oracle 11.2g

My code is:
set serveroutput on size unlimited;
DECLARE
v_line_unclean VARCHAR2(32767); -- 32767 BYTES
v_line_clean VARCHAR2(32767);
v_clean_val VARCHAR2(32767);
SQLSMT VARCHAR2(32767);
v_line_in_record INTEGER;
pattern varchar2(15) := '("[^"]*"|[^,]+)';
v_name VARCHAR2(50);
v_first_column VARCHAR2(200);
EMP_FILE UTL_FILE.FILE_TYPE;
BEGIN
DBMS_OUTPUT.ENABLE(9000000);
EMP_FILE := UTL_FILE.FOPEN('EGIS_FILE_DIR','TEST.csv','R', 32767); -- open the file from oracle directory
v_line_in_record := 0; --we skip the first line
IF UTL_FILE.IS_OPEN(EMP_FILE) THEN
LOOP
v_line_in_record := v_line_in_record + 1;
--DBMS_OUTPUT.PUT_LINE(v_line_in_record);
BEGIN
UTL_FILE.GET_LINE(EMP_FILE,v_line_unclean);
IF v_line_in_record = 1 THEN-- first record here
DBMS_OUTPUT.PUT_LINE('');
ELSIF v_line_in_record = 2 THEN-- second record here (header)
DBMS_OUTPUT.PUT_LINE('');
DBMS_OUTPUT.PUT_LINE(v_line_unclean);
v_first_column := SUBSTR(v_line_unclean,1,instr(v_line_unclean,',',10,1)-1);
dbms_output.put_line('1st '||REGEXP_SUBSTR(v_line_unclean, '[^,]+', 1, 1));
ELSE -- body records here);
SELECT REPLACE(v_line_unclean,'((\)|^).*?(\(|$))|,', '\1')INTO v_line_clean FROM DUAL;
SQLSMT := 'INSERT INTO SITE_CONFIG_2G VALUES('''||v_line_clean||''')';
EXECUTE IMMEDIATE SQLSMT;
END IF;
COMMIT;
DBMS_OUTPUT.PUT_lINE(SQLSMT);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_lINE('NO DATA FOUND EXCEPTION');
EXIT;
WHEN TOO_MANY_ROWS THEN
DBMS_OUTPUT.PUT_lINE('TO MANY ROW EXCEPTION');
EXIT;
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(sqlcode||sqlerrm);
ROLLBACK;
EXIT;
END;--EXCEPTION
END LOOP;
END IF;
UTL_FILE.FCLOSE(EMP_FILE);
END;
Result :
INSERT INTO SITE_CONFIG_2G VALUES('1,gold,benz,2018,1,blue,"34,000,000",6.4,new,CSV')
INSERT INTO SITE_CONFIG_2G VALUES('2,silver,bmw,2016,1,silver,"51,000,000",6.5,New,CSV')
INSERT INTO SITE_CONFIG_2G VALUES('3,bronze,range,2017,1,light-blue,"24,000,000",7.8,New,RVS')
I would like to remove commas between quotes in "24,000,000" to give me "24000000"
Current result is:
3,bronze,range,2017,1,light-blue,"24,000,000",7.8,New,RVS
Expected result is:
3,bronze,range,2017,1,light-blue,"24000000",7.8,New,RVS
can you try this.
select regexp_replace('1,gold,benz,2018,1,blue,"34,000,000",6.4,new,CSV',
'(")([^"|,]+)(,)([^"|,]+)(,)([^"|,]+)(")',
'\1\2\4\6\7') from dual;

Oracle PL/SQL - how do I run the same block of code for ALL exceptions?

Oracle 11g. This seems like it should be stupidly obvious, but I haven't seen an example. I have 2 exceptions which each need to write slightly different log messages, and then they should do the same UPDATE and CONTINUE.
Is there any way to structure the exception so I only need to type the UPDATE and CONTINUE statements once, while keeping the different logging?
FOR my_rec IN my_cursor
LOOP
BEGIN
...do some stuff
EXCEPTION
WHEN NO_DATA_FOUND THEN
log_detail.new('Skipping record - ID not found');
UPDATE my_table
SET operation_result = 'Failed'
WHERE my_id = my_rec.some_id;
CONTINUE;
WHEN OTHERS THEN
log_detail.new('Skipping record - unknown error');
UPDATE my_table
SET operation_result = 'Failed'
WHERE my_id = my_rec.some_id;
CONTINUE;
END;
END LOOP;
Did you try:
FOR my_rec IN my_cursor
LOOP
BEGIN
...do some stuff
EXCEPTION
WHEN OTHERS THEN
if sqlcode=-1403 then
log_detail.new('Skipping record - ID not found');
else
log_detail.new('Skipping record - unknown error');
end if;
UPDATE my_table
SET operation_result = 'Failed'
WHERE my_id = my_rec.some_id;
CONTINUE;
END;
END LOOP;
You could try:
DECLARE
vError VARCHAR2(1);
vMessage VARCHAR2(100);
BEGIN
FOR my_rec IN my_cursor LOOP
vError := 'N';
BEGIN
...do some stuff
EXCEPTION
WHEN NO_DATA_FOUND THEN
vError := 'S';
vMessage := 'Skipping record - ID not found';
WHEN OTHERS THEN
vError := 'S';
vMessage := 'Skipping record - unknown error';
END;
IF vError = 'S' THEN
log_detail.new(vMessage);
UPDATE my_table
SET operation_result = 'Failed'
WHERE my_id = my_rec.some_id;
CONTINUE;
END IF;
END LOOP;
END;

pl sql %NOTFOUND

I'm just wondering why this piece of code is not working. I don't have any supplier id=1 in my table.
DECLARE
VAR SUPP_NM VARCHAR(100);
VAR_SUPP_ID NUMBER := 1;
WHILE_VAR CHAR := 'Y';
BEGIN
SELECT SUPP_NM
INTO VAR_SUPP_NM
FROM TEST.SUPPLIER
WHERE SUPP_ID = VAR_SUPP_ID;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
ELSIF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('DATA FOUND');
END IF;
END;
I get a 01403 error in Toad but not handled as sql%notfound.
Why isn't the sql%notfound working?
To catch the NO_DATA_FOUND exception rewrite your code as follows by adding exception section:
DECLARE
VAR_SUPP_NM VARCHAR2(100);
VAR_SUPP_ID NUMBER := 1;
WHILE_VAR CHAR := 'Y';
BEGIN
SELECT SUPP_NM
INTO VAR_SUPP_NM
FROM TEST.SUPPLIER
WHERE SUPP_ID = VAR_SUPP_ID;
DBMS_OUTPUT.PUT_LINE('DATA FOUND');
exception
when no_data_found
then DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
END;
Checking SQL%FOUND or SQL%NOTFOUND have no meaning in the case of select into statement, because if the select statement returns no rows it will always raise no_data_found exception, except, if that select statement invokes aggregate function, it will always return data or null if no rows has been selected.
Do not use varchar datatype, use varchar2 datatype instead.
Nicholas's answer is what you want if you want to use SELECT INTO. However, if it is more important that you are able to use %FOUND or %NOTFOUND, consider FETCHing from a cursor instead:
DECLARE
VAR SUPP_NM VARCHAR2(100);
VAR_SUPP_ID NUMBER := 1;
WHILE_VAR CHAR := 'Y';
CURSOR c1 IS
SELECT SUPP_NM
FROM TEST.SUPPLIER
WHERE SUPP_ID = VAR_SUPP_ID;
BEGIN
OPEN c1;
FETCH c1 INTO VAR_SUPP_NM;
IF c1%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
ELSIF c1%FOUND THEN
DBMS_OUTPUT.PUT_LINE('DATA FOUND');
END IF;
CLOSE c1;
END;
Nick's answer is correct.
In oracle documentation however it is stated that SQL%NOTFOUND works with SELECT INTO but before one could check SQL%NOTFOUND to be TRUE an error is generated called as no_data_found.
so to use SQL%NOTFOUND one first needs to hande no_data_found error.
DECLARE
VAR SUPP_NM VARCHAR(100);
VAR_SUPP_ID NUMBER := 1;
WHILE_VAR CHAR := 'Y';
BEGIN
BEGIN
SELECT SUPP_NM
INTO VAR_SUPP_NM
FROM TEST.SUPPLIER
WHERE SUPP_ID = VAR_SUPP_ID;
EXCEPTION
WHEN NO_DATA_FOUND THEN
null; -- or write something here if u want.
END;
IF SQL%NOTFOUND THEN
DBMS_OUTPUT.PUT_LINE('SQL DATA NOT FOUND');
ELSIF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('DATA FOUND');
END IF;
END;
So what I have done is added a inner BEGIN-END block enclosing the SELECT statement that generates no_data_found exception. After that you can check for the value of SQL%NOTFOUND.
You can read more about this in oracle docs.
Start from this active link in mytime : https://docs.oracle.com/cd/B28359_01/appdev.111/b28370/errors.htm#LNPLS00703

update same record which fires a trigger

I want to update the same record which fires a trigger. I have done that using "BEFORE INSERT"
option. But note that I have use a transaction to rollback the operation if there is an any faliure.
CREATE OR REPLACE TRIGGER GANUKA.INTF_CONTROLLER_UPLOADER
BEFORE insert ON GANUKA.INTF_CONTROLLER for each row
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
max_id INTEGER;
stat VARCHAR2(32);
begin
select :new.id into max_id from dual;
select :new.status into stat from dual;
IF STAT = 'NEW' THEN --ONLY NEW UPLOADS WILL CONTINUE FOR PROCESS
:NEW.STATUS := 'STARTED';
max_id := GANUKA.BACKOFFICE_UPDATE(max_id); --PL/SQL function
:NEW.STATUS := 'COMPLETED';
ELSE
:NEW.STATUS := 'ABORTED';
:NEW.REMARKS :='STATUS IS NOT RECONGNIZED';
END IF;
COMMIT;
EXCEPTION
WHEN OTHERS
THEN
ROLLBACK;
RAISE;
end;
/
Problem is if there is an an any exception I want to update the record to set the state as 'Failed'. Can any one tell me how to do that.
I'm not sure why do you use autonomous transaction here and why do you have to commit/rollback in the trigger...
Does this do it?
CREATE OR REPLACE TRIGGER GANUKA.INTF_CONTROLLER_UPLOADER
BEFORE insert ON GANUKA.INTF_CONTROLLER for each row
DECLARE
max_id INTEGER;
stat VARCHAR2(32);
begin
max_id := :new.id;
stat := :new.status;
IF STAT = 'NEW' THEN --ONLY NEW UPLOADS WILL CONTINUE FOR PROCESS
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
max_id := GANUKA.BACKOFFICE_UPDATE(max_id); --PL/SQL function
COMMIT;
:NEW.STATUS := 'COMPLETED';
EXCEPTION
WHEN OTHERS THEN
ROLLBACK;
:new.status := 'FAILED';
END;
ELSE
:NEW.STATUS := 'ABORTED';
:NEW.REMARKS :='STATUS IS NOT RECONGNIZED';
END IF;
end;
/

Resources