An anonymous PL/SQL block:
DECLARE
CURSOR employees_in_10_cur
IS
SELECT *
FROM ad_week_table
BEGIN
FOR employee_rec
IN employees_in_10_cur
LOOP
DBMS_OUTPUT.put_line(employee_rec.ad_no || ',' || employee_rec.week_no);
END LOOP;
END;
I get a missing keyword error when I execute this block. What am I doing wrong?
put a semi-colon after defining cursor query;
DECLARE
CURSOR employees_in_10_cur
IS
SELECT *
FROM ad_week_table;
BEGIN
FOR employee_rec
IN employees_in_10_cur
LOOP
DBMS_OUTPUT.put_line (
employee_rec.ad_no || ',' || employee_rec.week_no );
END LOOP;
END;
You're missing a semi-colon at the end of your cursor:
CURSOR employees_in_10_cur
IS
SELECT *
FROM ad_week_table;
The error message will always give you the line number of the error occurring. Please always check this and look in that area.
For instance; if I change the table so I can run this I get the following:
SQL> declare
2
3 cursor employees_in_10_cur is
4 select *
5 from user_tables
6
7 begin
8 for employee_rec in employees_in_10_cur loop
9 dbms_output.put_line (
10 employee_rec.ad_no || ',' || employee_rec.week_no );
11 end loop;
12 end;
13 /
for employee_rec in employees_in_10_cur loop
*
ERROR at line 8:
ORA-06550: line 8, column 8:
PL/SQL: ORA-00905: missing keyword
ORA-06550: line 4, column 5:
PL/SQL: SQL Statement ignored
ORA-06550: line 11, column 4:
PLS-00103: Encountered the symbol "END" when expecting one of the following:
begin function pragma procedure subtype type <an identifier>
<a double-quoted delimited-identifier> current cursor delete
exists prior
You have 3 errors; one at line 8 because the cursor is invalid, one at line 11 because the loop doesn't happen because the cursor is invalid and one at line 4, which says "statement ignored".
Related
I have below code which checks for table exists & proceed further.
Here problem is why its proceeding to else part even though table is not present in the database & also its returning "0"
SQL> SET serveroutput ON trimspool on feed off echo on
declare
c_cnt number;
t_cnt number;
begin
select count(1) into t_cnt from dba_tables where owner='PRODDBA' and table_name='IOT_LIST';
dbms_output.put_line(t_cnt);
if t_cnt = 0 then
dbms_output.put_line('NO_ACTION');
else
select count(1) into c_cnt from PRODDBA.IOT_LIST;
if c_cnt = 0 then
dbms_output.put_line('NO_ACTION');
else
for i in (select temp_table_name from PRODDBA.IOT_LIST)
loop
begin
dbms_output.put_line(i.temp_table_name);
execute immediate 'drop table PRODDBA.'||i.temp_table_name||' purge';
EXCEPTION WHEN OTHERS then
CONTINUE;
end;
end loop;
end if;
end if;
end;
/
select count(1) into c_cnt from PRODDBA.IOT_LIST;
ERROR at line 10:
ORA-06550: line 10, column 41:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 10, column 1:
PL/SQL: SQL Statement ignored
ORA-06550: line 14, column 47:
PL/SQL: ORA-00942: table or view does not exist
ORA-06550: line 14, column 11:
PL/SQL: SQL Statement ignored
ORA-06550: line 17, column 22:
PLS-00364: loop index variable 'I' use is invalid
ORA-06550: line 17, column 1:
PL/SQL: Statement ignored
ORA-06550: line 18, column 42:
PLS-00364: loop index variable 'I' use is invalid
ORA-06550: line 18, column 1:
PL/SQL: Statement ignored
You should make use of dynamic REFCURSOR to run a loop to drop tables dynamically.
SET SERVEROUTPUT ON
DECLARE
c_cnt NUMBER;
t_cnt NUMBER;
v_schema_name VARCHAR2(40) := 'PRODDBA';
v_table_name VARCHAR2(40) := 'IOT_LIST';
v_tabs VARCHAR2(40);
refcur SYS_REFCURSOR;
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_ACTION');
ELSE
OPEN refcur FOR 'SELECT temp_table_name
FROM '||v_schema_name||'.'||v_table_name;
LOOP
BEGIN
FETCH refcur INTO v_tabs;
EXIT WHEN refcur%NOTFOUND;
EXECUTE IMMEDIATE 'drop table '||v_schema_name||'.'
|| v_tabs
|| ' purge';
dbms_output.put_line('DROPPED ' || v_tabs);
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line( 'TABLE NOT FOUND: '||v_tabs);
CONTINUE;
END;
END LOOP;
IF refcur%ROWCOUNT = 0 THEN
dbms_output.put_line('NO_ACTION');
END IF;
END IF;
END;
/
Result
Before table creation
<execute the block>
0
NO_ACTION
PL/SQL procedure successfully completed.
After table creation
create table IOT_LIST ( temp_table_name varchar2(40));
INSERT INTO IOT_LIST values('T1');
INSERT INTO IOT_LIST values('T2');
INSERT INTO IOT_LIST values('T4');
<execute the block>
1
DROPPED T1
DROPPED T2
TABLE NOT FOUND: T4
PL/SQL procedure successfully completed.
I have created two procedures like :
CREATE OR REPLACE procedure PARTNER_OWNER.test_1
as begin
dbms_output.put_line('Hello World 1 !');
end;
and
CREATE OR REPLACE procedure PARTNER_OWNER.test_2
as begin
dbms_output.put_line('Hello World 2 !');
end;
Now I need to drop the procedures at the same time (something like ):
drop procedure PARTNER_OWNER.test_*;
Is there a way to do that?
I would use a select statement to generate the drop statements and then run them.
select 'DROP PROCEDURE PARTNER_OWNER.'||object_name||';'
from dba_objects
where object_name like 'TEST_%' and
owner = 'PARTNER_OWNER';
Bobby
One option is to use dynamic SQL. Here's an example:
SQL> create or replace procedure test_1
2 as begin
3 dbms_output.put_line('Hello World 1 !');
4 end;
5 /
Procedure created.
SQL> create or replace procedure test_2
2 as begin
3 dbms_output.put_line('Hello World 2 !');
4 end;
5 /
Procedure created.
SQL> exec test_1;
Hello World 1 !
PL/SQL procedure successfully completed.
SQL> exec test_2;
Hello World 2 !
PL/SQL procedure successfully completed.
Now, drop them:
SQL> begin
2 for cur_r in (select object_name from user_objects
3 where object_type = 'PROCEDURE'
4 and object_name like 'TEST%')
5 loop
6 execute immediate 'drop procedure ' || cur_r.object_name;
7 end loop;
8 end;
9 /
PL/SQL procedure successfully completed.
The result:
SQL> exec test_1;
BEGIN test_1; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_1' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL> exec test_2;
BEGIN test_2; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_2' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
Alternatively, instead of using an anonymous PL/SQL block, you can rewrite it to a procedure and reuse it later. As it accepts a parameter, you can drop any procedure. Pay attention to LIKE (so that you wouldn't drop a procedure you didn't really want to).
SQL> create or replace procedure p_drop_prc(par_procedure_name in varchar2)
2 is
3 begin
4 for cur_r in (select object_name from user_objects
5 where `enter code here`object_type = 'PROCEDURE'
6 and object_name like upper(par_procedure_name) ||'%')
7 loop
8 execute immediate 'drop procedure ' || cur_r.object_name;
9 end loop;
10 end;
11 /
Procedure created.
SQL> exec p_drop_prc('test');
PL/SQL procedure successfully completed.
SQL> exec test_1;
BEGIN test_1; END;
*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_1' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
SQL>
Also, you could add another parameter - object type - so that you could drop any object, not just a procedure.
Obviously, quite a few options; pick the one you find the most appropriate.
I'm fairly new to Oracle but Ive been tasked to write this statement .
BEGIN
FOR partition IN 1..32 LOOP
lQuery := 'UPDATE CORE.tbl PARTITION(tbl' || LPAD(partition, 2, '0') || ') SET p = NULL '
|| 'WHERE p IS NOT NULL';
EXECUTE IMMEDIATE lQuery;
END LOOP;
END;
However, I get the following error
Error starting at line 1 in command:
BEGIN
FOR partition IN 1..32 LOOP
lQuery := 'UPDATE CORE.user_login PARTITION(user_login' || LPAD(partition, 2, '0') || ') SET password_md5 = NULL '
|| 'WHERE password_md5 IS NOT NULL';
EXECUTE IMMEDIATE lQuery;
END LOOP;
END;
Error report:
ORA-06550: line 3, column 5:
PLS-00201: identifier 'LQUERY' must be declared
ORA-06550: line 3, column 5:
PL/SQL: Statement ignored
ORA-06550: line 6, column 23:
PLS-00201: identifier 'LQUERY' must be declared
ORA-06550: line 6, column 5:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
when I try to run it. I understand that this might be because of not declaring lQuery but googling online showed me examples of declaring variables of a certain type such as (integer, varchar.. etc.) but none of them showed how to declare a query as this statement expects.
Your statement may be simply declared as a varchar2. For example:
declare
vsql varchar2(1000);
n integer;
begin
vsql := 'select 1 from dual';
execute immediate vsql into n;
dbms_output.put_line(n);
end;
thanks for all,i had modified from varchar2(10) to varchar2(20) and removing the column keyword in execute immediate statement then program is executing
declare
coldate varchar2(20);
colname varchar2(20);
begin
coldate :='varchar2(10)';
colname :='smaple';
execute immediate 'alter table smap1 add column '||colname ||' '||coldate ;
end;
if i want to take the values dynamically i had used the following code
declare
coldate varchar2(20):=&coldate;
colname varchar2(20):=&colname;
begin
execute immediate 'alter table smap1 add '||colname ||' '||coldate ;
end;
then i am getting errors
[Error] Execution (11: 23): ORA-06550: line 2, column 23:
PLS-00330: invalid use of type name or subtype name
ORA-06550: line 2, column 9:
PL/SQL: Item ignored
ORA-06550: line 3, column 23:
PLS-00201: identifier 'SMAPLE' must be declared
ORA-06550: line 3, column 9:
PL/SQL: Item ignored
ORA-06550: line 6, column 45:
PLS-00320: the declaration of the type of this expression is incomplete or malformed
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
declare
coldate varchar2(20);
colname varchar2(20);
begin
coldate :='varchar2(10)';
colname :='smaple';
execute immediate 'alter table smap1 add column '||colname ||' '||coldate ;
end;
This query wont work as syntactically its not correct.
Please try this as it will help you definitely
declare
coldate varchar2(20):='varchar2(20)';
colname varchar2(20):='Newadd';
begin
execute immediate 'alter table <tablename> add '||colname ||' '||coldate ;
end;
-- And to use dynamically input values Please try this
SET DEFINE ON;
declare
coldate varchar2(20):='&DATATYPE';
colname varchar2(20):='&COL_NAME';
begin
execute immediate 'alter table emp add '||colname ||' '||coldate ;
end;
The below will solve it:
coldate varchar2(12);
colname varchar2(20);
begin
coldate :='varchar2(10)';
I can't understand why do I get this error. I have the table but the code sample is not working properly. What's the problem here?
DECLARE
CURSOR c_cust(p_city VARCHAR2) IS
SELECT * FROM cust WHERE cust.city=p_city;
v_cust c_cust%ROWTYPE;
v_city c_cust%TYPE;
BEGIN
v_city := 'London';
OPEN c_cust (v_city);
LOOP
FETCH c_cust INTO v_cust;
EXIT WHEN (c_cust%NOTFOUND);
DBMS_OUTPUT.PUT_LINE (v_cust.cname || ' has ' || v_cust.rating);
END LOOP;
IF (c_cust%ISOPEN) THEN CLOSE c_cust;
END;
ORA-06550: line 15, column 4: PLS-00103:
Encountered the symbol ";"
when expecting one of the following: if
DECLARE
CURSOR c_cust(p_city VARCHAR2) IS
SELECT * FROM cust WHERE cust.city=p_city;**
c_cust%ISOPEN should be before end loop;
If .... then
....
end if;
you miss the end if;