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'')';
Related
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;
...
error screenshot I am trying to execute the below program in Toad.
create or replace procedure tst_excp as
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = &var_empid;
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;
and I am getting an error at the line: where empno = &var_empid;
error message is:
PL/SQL: ORA-00936: missing expression
I am planning to pass the value to the variable while executing it.
the & is part of the sqlplus (and TOAD, SQL Developer and PL/SQL Developer) runtime variables. it will prompt you on execution (in your case while compiling the procedure) for an input to replace in the code.
if you want the get an input for the procedure, so it will be added to the where clause on every run, you need to receive it as an input variable:
create or replace procedure tst_excp (var_empid in number) as -- << changed here
var_sal number;
var_empid number;
var_excp exception;
begin
select sal into var_sal from emp
where empno = var_empid; -- << changed here too
if var_sal < 4500 then
raise var_excp;
end if;
exception
when var_excp then
dbms_output.put_line ('The salary is low');
end;
My whole intention to catch exception,WRONG parameter is NOT CATCHING exception.
Here is the code:
CREATE OR REPLACE PROCEDURE list_emp (p_emp_id IN employees.employee_id%TYPE,
p_dept_id IN employees.department_id%TYPE)
IS
CURSOR c1 IS
SELECT *
FROM EMPLOYEES
WHERE EMPLOYEE_ID=p_emp_id
AND DEPARTMENT_ID=p_dept_id;
emp_rec c1%ROWTYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO emp_rec;
EXIT WHEN c1%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(emp_rec.employee_id||' '||emp_rec.first_name||' '||emp_rec.last_name);
END LOOP;
CLOSE c1;
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('No Record Found ');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('No Record Found ');
END;
When the cursor is opened and fetched with the wrong parameter that does not match any row from the corresponding table, the following line
EXIT WHEN c1%NOTFOUND;
cause the plsql procedure to terminate (because there were no rows found). Hence no exception is raised.
If you do want to display some sort of output you can do the following instead
IF c1%FOUND THEN
dbms_output.put_line('Record Found');
ELSE
dbms_output.put_line('Finished/Done');
EXIT;
END IF;
If you want to raise an error after looping through a cursor that returns no rows, then you're going to have to use a counter to work out how many rows have been processed, and then you can do something if no rows have been processed.
Something like:
create or replace procedure list_emp (p_emp_id in employees.employee_id%type,
p_dept_id in employees.department_id%type)
is
cursor c1 is
select employee_id,
first_name,
last_name
from employees
where employee_id = p_emp_id
and department_id = p_dept_id;
v_count number := 0;
begin
for emp_rec in c1
loop
v_count := v_count + 1;
dbms_output.put_line(emp_rec.employee_id||' '||emp_rec.first_name||' '||emp_rec.last_name);
end loop;
if v_count = 0 then
raise no_data_found;
end if;
exception
when no_data_found then
dbms_output.put_line('No Record Found.');
raise;
when others then
dbms_output.put_line('An error occurred: '||sqlerrm);
raise;
end;
/
A few notes:
I converted your cursor loop into a cursor-for-loop; you don't need to worry about declaring the record type and also Oracle handles the opening and closing of the cursor for you.
I added raise; to each of your exception handlers - in general, having when others then null (which is effectively what your original code was doing - no errors are raised to the calling code) is a bad idea. I added the raise to the no_data_found condition as that wasn't doing anything either; typically, if you have an exception condition, you want it to do something to let the calling code know there was a problem (not always, of course; sometimes you don't want the processing to stop if a particular error condition is met).
Your cursor was selecting all columns, but in your procedure, you were only using three of them. I've therefore amended the cursor so that it only pulls back those three columns.
Don't rely on dbms_output in your production code. Code that calls this procedure won't see anything populated in dbms_output, unless it explicitly looks for it - and that's not something I've ever seen in any production code, outside of Database tools (eg. SQL*Plus, Toad, etc). I've left this in your procedure as I've a feeling this is a learning exercise for you, but please don't think that this is in any way acceptable in production code.
You're passing p_emp_id in as a parameter - typically, that's the primary key of the employees table. If that's the case, then there's no need for the cursor for loop at all - you could do it by using select ... into ... instead, like so:
.
create or replace procedure list_emp (p_emp_id in employees.employee_id%type,
p_dept_id in employees.department_id%type)
is
v_emp_id employees.employee_id%type;
v_first_name employees.first_name%type;
v_last_name employees.last_name%type;
begin
select employee_id,
first_name,
last_name
into v_emp_id,
v_first_name,
v_last_name
from employees
where employee_id = p_emp_id
and department_id = p_dept_id;
dbms_output.put_line(emp_rec.employee_id||' '||emp_rec.first_name||' '||emp_rec.last_name);
exception
when no_data_found then
dbms_output.put_line('No Record Found.');
raise;
when others then
dbms_output.put_line('An error occurred: '||sqlerrm);
raise;
end;
/
Alternatively, just pass back a ref cursor:
create or replace procedure list_emp (p_emp_id in employees.employee_id%type,
p_dept_id in employees.department_id%type,
p_ref_cur out sys_refcursor)
is
begin
open p_ref_cur for select employee_id,
first_name,
last_name
from employees
where employee_id = p_emp_id
and department_id = p_dept_id;
-- No need for an exception handler here since you're not storing the error details anyway.
-- By not having an error handler, any error will automatically be raised up to the calling code
-- and it will have the correct error stack trace info (e.g. the line number the error occurred,
-- rather than the line the error was reraised from
end;
/
And to run the ref cursor in SQL*Plus (or as a script in Toad/SQL Developer/etc), you do the following:
-- create a variable outside of PL/SQL to hold the ref cursor pointer (this is a SQL*Plus command):
variable rc refcursor;
-- populate our ref cursor variable with the pointer. Note how we pass it in as a bind variable
begin
list_emp(p_emp_id => 1234,
p_dept_id => 10,
p_ref_cur => :rc);
end;
/
-- finally, print the contents of the ref cursor.
print rc;
I have table named "players" like this
Name Country
---------- ------------
Sachin India
Ponting Australia
I have written a PL/SQL Procedure to execute it by giving "name" as parameter.
Here is the code-
CREATE OR REPLACE PROCEDURE NEW_TEST ( player IN players.name%type, place IN players.country%type ) IS
countri players.country%type;
BEGIN
SELECT country into countri from players where name = player;
END;
DECLARE
player players.name%type;
place players.country%type;
CURSOR cu_new0 is
SELECT name, country from players where name=player;
BEGIN
player:='Sachin' ;
FOR pl_all in cu_new0
LOOP
NEW_TEST (player, place);
dbms_output.put_line ('The player ' || player || ' play for ' || pl_all.country);
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No such player!');
WHEN OTHERS THEN
dbms_output.put_line('Error!');
END;
Now when I am putting player:='Sachin' it is giving output but when I am giving player:= 'Sachin1' is not showing any output and more importantly it is not even going to exception of 'NO_DATA_FoUND'. Can you please help me in this regard. Thanx
If you code a loop, Oracle does not throw an exception if no data is returned (just as it doesn't throw a TOO_MANY_ROWS exception if more than one row is returned).
Your one of the select clause is not handling exception; you are consuming exception in that code.
Your Original Code:
BEGIN
SELECT country into countri from players where name = player;
END;
Modify with below code--
BEGIN
SELECT country into countri from players where name = player;
exception when no_data_found then
raise_application_error(......);
END;
DECLARE
player players.name%type;
place players.country%type;
CURSOR cu_new0 is
SELECT name, country from players where name=player;
type l_cu_new0 is table of cu_new0%rowtype;
v_cu_new0 l_cu_new0;
BEGIN
player:='Sachin' ;
open cu_new0;
fetch cu_new0 bulk collect into v_cu_new0;
close cu_new0;
if v_cu_new0.count = 0 then
raise NO_DATA_FOUND;
end;
FOR i in v_cu_new0.first .. v_cu_new0.last
LOOP
...
END LOOP;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No such player!');
WHEN OTHERS THEN
dbms_output.put_line('Error!');
END;
There are your cursor is NULL. Because;
Temp code block :
select name
,country
from players
where name = :player;
Run code block :
select name
,country
from players
where name = 'Schin1';
Run code block return NULL and your cursor is have NULL value.
Then your for loop code block is not work.
You can solve this problem such as ;
CURSOR cu_new0 is
SELECT name, country from players;
Hi #Warrior92 for edit,
There are maybe you can try it ;
for pl_all in cu_new0 loop
new_test(player
,place);
if pl_all.name = player then
dbms_output.put_line('The player ' || player || ' play for ' || pl_all.country);
end if;
end loop;
If you really want to use a cursor, the for loop and an exception, you can try the following code:
DECLARE
-- create table type of players
TYPE t_players_tab IS TABLE OF players%ROWTYPE;
-- declare variable / array which will contain the result of cursor's select
l_players_arr t_players_tab := NEW t_players_tab();
CURSOR c_fetch_player IS
SELECT
*
FROM
players
WHERE
name = player;
-- declare exception which is to be caught within the EXCEPTION block
EXCEPTION e_player_not_found;
-- init the exception giving it the sqlcode -20001 (valid numbers for custom exceptions are in range from -20000 to -20999)
PRAGMA EXCEPTION_INIT(e_player_not_found, -20001);
BEGIN
-- fetch the cursor result into the array
OPEN c_fetch_player;
FETCH c_fetch_player BULK COLLECT INTO l_players_arr;
CLOSE c_fetch_player;
-- check if the array contains any results
IF l_players_arr.COUNT > 0 THEN
-- iterate through the rows in the array
FOR idx l_players_arr.FIRST .. l_players_arr.LAST
LOOP
dbms_output.put_line ('The player ' || player || ' play for ' || l_players_arr(idx).country);
END LOOP;
ELSE -- if the array has no rows, raise application arror with the same sqlcode as defined in EXCEPTION_INIT
raise_application_error(-20001,'Player ' || player || 'not found');
END IF;
EXCEPTION
-- catch the exception
WHEN e_player_not_found THEN
dbms_output.put_line(sqlcode || ': ' || sqlerrm);
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_CALL_STACK);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_STACK);
DBMS_OUTPUT.PUT_LINE(DBMS_UTILITY.FORMAT_ERROR_BACKTRACE);
END;
/
I'm trying to catch an exception within my anonymous PL/SQL block
DECLARE
...
BEGIN
FOR herstell_row IN (
...
)
LOOP
...
DECLARE
table_does_not_exists exception;
pragma exception_init( table_does_not_exists, -942 );
BEGIN
INSERT INTO SMART_MONITORING_MACHINE_NAV_B (
MACHINE,
NAVIGATION_LEVEL_ID
)
SELECT
old_binding.MACHINE,
pv_id
FROM
SMART_MACHINE_NAV_BINDING old_binding
WHERE
old_binding.NAVIGATION_LEVEL_ID = herstell_row.HENAME1;
EXCEPTION
WHEN table_does_not_exists THEN null;
END;
END LOOP;
END;
I know the table SMART_MACHINE_NAV_BINDING doesn't exist in my case, so I need the nested anonymous block to ignore its code. But I always get this error:
Error report -
ORA-06550: line 41, column 14:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 33, column 10:
PL/SQL: SQL Statement ignored
You can't compile code with non-existent table, but you can try to execute it using EXECUTE EMMEDIATE:
DECLARE
...
BEGIN
FOR herstell_row IN (
...
)
LOOP
...
DECLARE
table_does_not_exists exception;
pragma exception_init( table_does_not_exists, -942 );
BEGIN
execute immediate
'INSERT INTO SMART_MONITORING_MACHINE_NAV_B (
MACHINE,
NAVIGATION_LEVEL_ID
)
SELECT
old_binding.MACHINE,
pv_id
FROM
SMART_MACHINE_NAV_BINDING old_binding
WHERE
old_binding.NAVIGATION_LEVEL_ID = :P' using herstell_row.HENAME1;
EXCEPTION
WHEN table_does_not_exists THEN null;
END;
END LOOP;
END;
Also you don't need exceptions here, you can check existence of a table using system view:
declare
table_created number;
begin
select count(*)
into table_created
from all_tables
where table_name = ...
and owner = ...;
if table_created > 0 then
execute immediate 'insert into ...';
end if;
end;
More information about EXECUTE IMMEDIATE statement: http://docs.oracle.com/cd/E11882_01/appdev.112/e25519/executeimmediate_statement.htm#LNPLS01317
Oracle does not know this error table_does_not_exists it is user defined, so you should handle in when others then, for eg.
Exception
When Others then
null;
-- or at this time you can raise your error table_does_not_exists
raise table_does_not_exists;
-- and handle it in another parent block
end;
Exception
when table_does_not_exists then
null;
end;