Compilation error with plsql procedure - plsql

Below is a plsql procedure which was written by someone else and I have asked to fix its compilation errors and run it right.
PROCEDURE DropMyTable IS
x number;
TYPE cur_typ IS REF CURSOR;
--type NAME_TBL is table of VARCHAR2(30);
--tab_Table NAME_TBL;
tab_Table VARCHAR2S(30);
stmt VARCHAR2(4096);
stmt2 VARCHAR2(4096);
outerCur cur_typ;
rows NATURAL := 1000;
TABLE_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942);
BEGIN
stmt2 := 'select distinct G_Tab from G_SERVE where G_TYPE=''CAP''';
--Begin
OPEN outerCur FOR stmt2;
LOOP
FETCH outerCur BULK COLLECT INTO
tab_Table LIMIT rows;
EXIT WHEN tab_Table.COUNT = 0;
FOR i IN 1..tab_Table.COUNT LOOP
--------------------------------------------------------------------
-- Drop the tables in G_SERVE.G_TAB
DBMS_OUTPUT.PUT_LINE('*** Drop table: ' || tab_Table(i) || ' ***');
-- BEGIN
--First drop the optable
stmt := 'DROP TABLE ' || tab_Table(i) || '_OPTAB CASCADE CONSTRAINTS';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
--drop the base table
stmt := 'DROP TABLE ' || tab_Table(i) || ' CASCADE CONSTRAINTS';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
--drop the Package
stmt := 'DROP PACKAGE ' || tab_Table(i) || '_PKG';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
EXCEPTION
-- When the table, optab and package doesn't exist,
-- ignore error "ORA-00942: table, optab or package does not exist".
WHEN TABLE_DOES_NOT_EXIST THEN
DBMS_OUTPUT.PUT_LINE('table, optab or package does not exist');
DBMS_OUTPUT.PUT_LINE(CHR(9));
--Re-raises any other errors.
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error!');
RAISE;
END;
END LOOP;
END LOOP;
--END;
END DropMyTable;
First up I have commented out 4th and 5th line of code from begging and changed it to what it looks like now ( 6th line from the top).
Other thing I have commented out 2 BEGIN keywords first commented out "BEGIN" can be seen after
stmt2 := 'select distinct gao_table from GAO_SERVICESIFACE where GAO_TYPE=''CAPABILITY''';
and the second "BEGIN" keyword has been commented out after the following line of code.
DBMS_OUTPUT.PUT_LINE('*** Drop table: ' || tab_Table(i) || ' ***');
Since I suspect that whoever has written this code put unnecessary "BEGIN" keyword (i apologize if I'm wrong as I'm not a plsql expert. But doing all the commenting out thing i got rid of so many errors).
But when I compile the above code I still get following 2 errors.
1)
ORA-06550: line 27, column 7:
PLS-00103: Encountered the symbol "EXCEPTION" when expecting one of the following:
;
( begin case declare 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
2)
ORA-06550: line 38, column 9:
PLS-00103: Encountered the symbol "LOOP" when expecting one of the following:
;
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:

You have commented out the BEGIN inside the inner loop but not its associated EXCEPTION and END. You need that begin. Also you cannot change an array to a scalar variable while the code still expects an array (references to tab_Table(i) etc.)
Decent indentation of code always makes it easier to follow:
PROCEDURE DropMyTable IS
x number;
TYPE cur_typ IS REF CURSOR;
type NAME_TBL is table of VARCHAR2(30);
tab_Table NAME_TBL;
--tab_Table VARCHAR2S(30);
stmt VARCHAR2(4096);
stmt2 VARCHAR2(4096);
outerCur cur_typ;
rows NATURAL := 1000;
TABLE_DOES_NOT_EXIST EXCEPTION;
PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942);
BEGIN
stmt2 := 'select distinct G_Tab from G_SERVE where G_TYPE=''CAP''';
--Begin
OPEN outerCur FOR stmt2;
LOOP
FETCH outerCur BULK COLLECT INTO
tab_Table LIMIT rows;
EXIT WHEN tab_Table.COUNT = 0;
FOR i IN 1..tab_Table.COUNT LOOP
--------------------------------------------------------------------
-- Drop the tables in G_SERVE.G_TAB
DBMS_OUTPUT.PUT_LINE('*** Drop table: ' || tab_Table(i) || ' ***');
BEGIN
--First drop the optable
stmt := 'DROP TABLE ' || tab_Table(i) || '_OPTAB CASCADE CONSTRAINTS';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
--drop the base table
stmt := 'DROP TABLE ' || tab_Table(i) || ' CASCADE CONSTRAINTS';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
--drop the Package
stmt := 'DROP PACKAGE ' || tab_Table(i) || '_PKG';
DBMS_OUTPUT.PUT_LINE(stmt);
EXECUTE IMMEDIATE stmt;
EXCEPTION
-- When the table, optab and package doesn't exist,
-- ignore error "ORA-00942: table, optab or package does not exist".
WHEN TABLE_DOES_NOT_EXIST THEN
DBMS_OUTPUT.PUT_LINE('table, optab or package does not exist');
DBMS_OUTPUT.PUT_LINE(CHR(9));
--Re-raises any other errors.
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error!');
RAISE;
END;
END LOOP;
END LOOP;
--END;
END DropMyTable;
I have reinstated that BEGIN and restored the array. I don't know if there is anything else wrong.

Related

ORA-00933 runtime plsql throwing the error

I am trying to query the dba_tables, if table "SPLIT_EXT_INFO" not present i am getting correct output, if table "SPLIT_EXT_INFO" exist i am getting below error,
SET serveroutput ON
DECLARE
t_cnt NUMBER;
v_schema_name VARCHAR2(40) := 'DBA';
v_table_name VARCHAR2(40) := 'SPLIT_EXT_INFO';
refcur SYS_REFCURSOR;
split_mapper VARCHAR2(40);
info_tab VARCHAR2(40);
tracker VARCHAR2(40);
BEGIN
SELECT Count(1)
INTO t_cnt
FROM dba_tables
WHERE owner = v_schema_name
AND table_name = v_table_name;
dbms_output.Put_line(t_cnt);
IF t_cnt = 0 THEN
dbms_output.Put_line('NO_SPLIT_TAB');
ELSE
OPEN refcur FOR 'SELECT split_mapper, info_tab, tracker FROM '
||v_schema_name
||'.'
||v_table_name
|| 'where nodename = ''host1.world.com''';
LOOP
FETCH refcur INTO split_mapper,info_tab,tracker;
EXIT WHEN refcur%NOTFOUND;
dbms_output.Put_line(split_mapper
||':'
||info_tab
||':'
||tracker);
END LOOP;
IF refcur%rowcount = 0 THEN
dbms_output.Put_line('NO_SPLIT_ENTRY');
END IF;
END IF;
CLOSE refcur;
END;
/
Error:
1
DECLARE
*
ERROR at line 1:
ORA-00933: SQL command not properly ended
ORA-06512: at line 21
can someone add help in this, thanks !
Regards
Kannan
The apostrophe symbol is on a wrong place before WHERE clause is being concatenated
your code: || 'where nodename = ''host1.world.com''';
right is : ||' where nodename = ''host1.world.com''';
In your version the sql will look like
select ... FROM tableWHERE nomename = ...
The missing space symbol between table name and WHERE causing this problem

Returning table results from a dynamic PL/SQL query

Trying to dynamically generate and execute a PL/SQL statement. It doesn't return results, but executing okay. What I am trying is to get the table name from the schema in first statement (got it right!), and append that to a select statement, and then execute it to return the table results.
DECLARE
LATEST_TABLE VARCHAR2(256);
PostalCode ADM.POSTAL_CODE_201801%ROWTYPE;
BEGIN
SELECT TO_CHAR(max(table_name)) INTO LATEST_TABLE FROM all_tables WHERE owner = 'ADM' AND table_name LIKE 'POSTAL_CODE_%';
LATEST_TABLE := 'begin Select POSTALCODE,LONGITUDE,LATITUDE,MUNICIPALITY_FULL_NAME,LOCAL_NAME,SZONE_NAME,ZONE_NAME,RHA_CODE,RHA_NAME,URBAN,ZONE_RURAL from ADM.'||LATEST_TABLE||' ;end;';
execute immediate LATEST_TABLE into PostalCode;
Exception
When others then
Null;
END;
Why am I not getting any results? Adding
dbms_output.put_line(PostalCode.LONGITUDE || PostalCode.LATITUDE); after execute immediate is also not generating results!
I see a couple of issues here; your code is something like:
declare
vSQL varchar2(1000);
vTabName varchar2(30);
vResult number;
begin
select table_name into vTabName from user_tables;
vSQL := 'begin select a from ' || vTabName || '; end;';
execute immediate vSQL into vResult;
dbms_output.put_line('REsult: ' || vResult);
exception
when others then
null
end;
If you run this, you see nothing, because the dynamic part gives error, but the (dangerous) exception handling hides it; if you would edit the null; into something like
dbms_output.put_line('Error: ' || sqlerrm);
you would get:
Error: ORA-06550: line 1, column 7:
PLS-00428: an INTO clause is expected in this SELECT statement
In fact you dynamic code is like
begin select a from someTable; end;
and this gives error.
A way to do what you need could be:
...
vSQL := 'select a from ' || vTabName;
execute immediate vSQL into vResult;
...

PLSQL Loop Through 100 Row at a time to delete

I tried below code to fetch the 1000 rows and loop through to delete 100 row at a time.
DECLARE
COUNTER INTEGER :=0;
v_delstr varchar2(2000);
v_countstr varchar2(2000);
SchemaName Varchar2(40):='Staging';
TableName Varchar2(100):='History';
BEGIN
LOOP
COUNTER := COUNTER + 1;
DBMS_OUTPUT.PUT_LINE('Counter: ');
v_delstr:= 'Delete FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 1000 And startdate>=sysdate-731 and startdate<=sysdate-730';
execute immediate v_delstr;
dbms_output.put_line(v_delstr);
v_countstr:= 'BEGIN
DECLARE CANT INTEGER;
SELECT COUNT(*) INTO CANT FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 1000 And startdate>=sysdate-731 and startdate<=sysdate-730;
EXIT WHEN CANT <= 100;
COMMIT;
END;';
execute immediate v_countstr;
dbms_output.put_line(v_countstr);
--dbms_output.put_line(v_delstr);
--dbms_output.put_line(v_countstr);
END LOOP;
END;
DECLARE
COUNTER INTEGER :=0;
v_delstr varchar2(2000);
v_countstr varchar2(2000);
SchemaName Varchar2(40):='Staging';
TableName Varchar2(100):='History';
BEGIN
LOOP
COUNTER := COUNTER + 1;
DBMS_OUTPUT.PUT_LINE('Counter: ');
v_delstr:= 'Delete FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 10 And startdate>=sysdate-731 and startdate<=sysdate-730';
execute immediate v_delstr;
dbms_output.put_line(v_delstr);
v_countstr:= 'BEGIN
DECLARE CANT INTEGER;
SELECT COUNT(*) INTO CANT FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 10 And startdate>=sysdate-731 and startdate<=sysdate-730;
EXIT WHEN CANT <= 1;
COMMIT;
END;';
execute immediate v_countstr;
dbms_output.put_line(v_countstr);
--dbms_output.put_line(v_delstr);
--dbms_output.put_line(v_countstr);
END LOOP;
END;
Got Error
Error report -
ORA-06550: line 3, column 23:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
The symbol "begin" was substituted for "SELECT" to continue.
ORA-06550: line 6, column 18:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
( begin case declare end exception 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
ORA-06512: at line 22
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I am not sure what's your purpose on the code but try this. it will work most probably.
DECLARE
COUNTER INTEGER :=0;
v_delstr VARCHAR2(2000);
v_countstr VARCHAR2(2000);
SchemaName VARCHAR2(40) :='Staging';
TableName VARCHAR2(100):='History';
BEGIN
FOR COUNTER IN 0..9
LOOP
COUNTER := COUNTER + 1;
DBMS_OUTPUT.PUT_LINE('Counter: ');
v_delstr:= 'Delete FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 1000 And startdate>=sysdate-731 and startdate<=sysdate-730';
EXECUTE immediate v_delstr;
dbms_output.put_line(v_delstr);
v_countstr:= 'DECLARE
CANT INTEGER;
BEGIN
SELECT COUNT(*) INTO CANT FROM ' ||SchemaName ||'.'||TableName|| ' where rownum <= 1000 And startdate>=sysdate-731 and startdate<=sysdate-730;
EXIT WHEN CANT <= 100;
COMMIT;
END;';
EXECUTE immediate v_countstr;
dbms_output.put_line(v_countstr);
--dbms_output.put_line(v_delstr);
--dbms_output.put_line(v_countstr);
END LOOP;
END;

Duplicate INSERT record procedure

I have problem with mu procedure which insert duplicate last record in table
example when I put INSERT..... 'AAA' I got to rows in table 'AAA' and 'AAA'
In place when I put DBMS()... in code I got tow records
I use trigger and sequence for column ID in HistoriaDismissDate but they are in good condition. I check if I dropped trigger and sequence and its the same situation
I also use viewDate but this view get mi ONE record not two
my code
CREATE OR REPLACE PROCEDURE ChangeDismissDate
IS
v_id VARCHAR2(11);
v_dateBhd DATE := TO_DATE('20491231','yyyymmdd');
v_dateDismiss DATE := TO_DATE('20491231','yyyymmdd');
v_login VARCHAR2(50);
last_id NUMBER :=0;
CURSOR cur IS
select EMP_NO, LOGIN, ODEJSCIE_BHD, ODEJSCIE_OLD FROM viewDate;
BEGIN
OPEN cur;
LOOP
FETCH cur INTO v_id,v_login,v_dateBhd,v_dateDismiss;
DBMS_OUTPUT.put_line(v_id || ' ' || v_login || ' ' || v_dateBhd || ' ' || v_dateDismiss);
UPDATE employee_tab SET DISMISS_DATE = v_dateBhd WHERE EMP_NO = v_id;
COMMIT;
INSERT INTO HistoriaDismissDate(CUSTOMER_ID,LOGIN, DATE_CHANGE, DATE_BHD, DATE_DISMISS)
VALUES(v_id,v_login, sysdate, v_dateBhd, v_dateDismiss);
COMMIT;
EXIT WHEN cur%NOTFOUND;
END LOOP;
CLOSE cur;
EXCEPTION
WHEN NO_DATA_FOUND
THEN
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
WHEN OTHERS
THEN
DBMS_OUTPUT.put_line (DBMS_UTILITY.format_error_stack);
END;
/
2 tips on your original code:
1) cursor is a very old programming technic on PL/SQL. Prefer to use FOR ... LOOP construction. It's cleaner and less error-prone! See how it works:
CREATE OR REPLACE PROCEDURE ChangeDismissDate IS
BEGIN
for cur in (select EMP_NO, LOGIN, ODEJSCIE_BHD, ODEJSCIE_OLD FROM viewDate) loop
DBMS_OUTPUT.put_line(cur.EMP_NO || ' ' || cur.login || ' ' || cur.ODEJSCIE_BHD || ' ' || cur.ODEJSCIE_OLD);
UPDATE employee_tab
SET DISMISS_DATE = cur.ODEJSCIE_BHD
WHERE EMP_NO = cur.EMP_NO;
INSERT INTO HistoriaDismissDate
( CUSTOMER_ID,LOGIN, DATE_CHANGE, DATE_BHD, DATE_DISMISS )
VALUES
( cur.EMP_NO, cur.LOGIN, sysdate, cur.ODEJSCIE_BHD, cur.ODEJSCIE_OLD, );
end loop;
end;
/
2) Never, I mean never put a commit inside your procedure. The commit should be done on the caller block or on your client-side app. When you put a commit inside your procedure, you miss the chance to rollback after running it and other procedures could not call it if they want to control the transaction flow.

PL/SQL: ORA-00942: table or view does not exist

Am getting this error 'PL/SQL: ORA-00942: table or view does not exist' in Oracle 11G when I try to runt his portion of my script. It seems the select statement isn't parsing the name of the variable from the cursor. Need help to ensure this can read the table name variable from the cursor.
DECLARE
ITEM_ERROR NUMBER;
CNT_SITE VARCHAR2(46);
CURSOR C_SITEID IS
SELECT OBJECTNAME,ATTRIBUTENAME FROM MAXATTRIBUTE WHERE ATTRIBUTENAME LIKE 'SITE%' GROUP BY OBJECTNAME,ATTRIBUTENAME, COLUMNNAME;
SITEIDRec C_SITEID%RowType;
BEGIN
BEGIN
OPEN C_SITEID;
LOOP
FETCH C_SITEID into SITEIDRec;
EXIT WHEN C_SITEID %NOTFOUND;
BEGIN
SELECT COUNT(SITEID) into CNT_SITE FROM SITEIDRec.OBJECTNAME
WHERE SITEID IN ('COLLEGE NANO SCI ENG-TGCM','FREESCALE-BALAZS','TGCM-GLOBAL FOUNDRIES','INTL RECTIFIER-TGM','TGCM-DMOS5','TGCM-IMFT','TGCM-TRIQUINT','GP-TRIQUINT');
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
END LOOP;
--COMMIT;
CLOSE C_SITEID;
--COMMIT;
EXCEPTION
WHEN NO_DATA_FOUND THEN NULL;
END;
--COMMIT;
EXCEPTION
WHEN OTHERS THEN
MSG_TEXT := SUBSTR(SQLERRM,1,200);
--COMMIT;
raise;
END;
I think you have FROM TableName missing in your query and hence it's rightly complaining.
SELECT COUNT(SITEID) into SITEIDRec.OBJECTNAME
WHERE SITEID IN
('COLLEGE NANO SCI ENG-TGCM','FREESCALE-BALAZS',
'TGCM-GLOBAL FOUNDRIES','INTL RECTIFIER-TGM','TGCM-DMOS5',
'TGCM-IMFT','TGCM-TRIQUINT','GP-TRIQUINT');
Please correct your query by adding the From TableName.
EDIT: Try using EXECUTE IMMEDIATE as below
EXECUTE IMMEDIATE 'SELECT COUNT(SITEID) into CNT_SITE FROM '
|| SITEIDRec.OBJECTNAME ||
' WHERE SITEID IN (''COLLEGE NANO SCI ENG-TGCM'',''FREESCALE-BALAZS'',
''TGCM-GLOBAL FOUNDRIES'',''INTL RECTIFIER-TGM'',''TGCM-DMOS5'',
''TGCM-IMFT'',''TGCM-TRIQUINT'',''GP-TRIQUINT'')';

Resources