array in oracle block - oracle

I have oracle block like
DECLARE
TYPE emp_array IS VARRAY(100) OF VARCHAR2(30);
VAR_PRESENTADDRESS1 varchar2(100);
emps emp_array;
inx1 PLS_INTEGER;
BEGIN
VAR_PRESENTADDRESS1 := 'test,test1';
emps := emp_array (select REGEXP_SUBSTR(VAR_PRESENTADDRESS1, '[^,]+', 1, rownum) addressword
from DUAL
connect by level <= length (regexp_replace (VAR_PRESENTADDRESS1, '[^,]+')) + 1);
FOR inx1 IN 1..2 LOOP
DBMS_OUTPUT.PUT_LINE(emps(inx1));
END LOOP;
END;
/
This gives error like :
Error report:
ORA-06550: line 9, column 28:
PLS-00103: Encountered the symbol "SELECT" when expecting one of the following:
( ) - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
table continue avg count current exists max min prior sql
stddev sum variance execute multiset the both leading
trailing forall merge year month day hour minute second
timezone_hour timezone_minute timezone_region timezone_abbr
time timestamp interval date
<a string literal with character set specifica
ORA-06550: line 11, column 112:
PLS-00103: Encountered the symbol ")" when expecting one of the following:
* & - + ; / at for mod remainder rem <an exponent (**)> and
or group having intersect minus order start union where
connect ||
ORA-06550: line 17, column 3:
PLS-00103: Encountered the symbol "end-of-file" when expecting one of the following:
end not pragma final instantiable order overriding static
member constructor map
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
I want output like:
test
test1

That's not how PL/SQL syntax works. Try this:
select REGEXP_SUBSTR(VAR_PRESENTADDRESS1, '[^,]+', 1, rownum)
bulk collect into emps
from DUAL
connect by level <= length (regexp_replace (VAR_PRESENTADDRESS1, '[^,]+')) + 1);

Related

Encountered the symbol "SELECT" when expecting one of the following:

i need help from you guys.
I am using oracle apex for university, and my task is to create triggers. I'm struggling a lot creating them, I don't even know what is wrong with this trigger. Can someone help me?
I get error
Encountered the symbol "SELECT" when expecting one of the following: ( - + case mod new not null <an identifier> <a double-quoted delimited-identifier> <a bind variable> continue avg count current exists max min prior sql stddev sum variance execute forall merge time timestamp interval date <a string literal with character set specification> <a number> <a single-quoted SQL string> pipe <an alternatively-quoted string literal with character set specification> <an alternat
Error at line 3: PLS-00049: bad bind variable 'NEW'
Error at line 3: PLS-00103: Encountered the symbol "" when expecting one of the following: . ( * # % & = - + ; < / > at for in is mod remainder not rem <an exponent (**)> <> or != or ~= >= <= <> and or like like2 like4 likec between group having intersect minus order start union where connect || indicator multiset member submultiset
Error at line 3: PLS-00049: bad bind variable 'CONTRACT' Error at line 3: PLS-00049: bad bind variable 'CONTRACT' -
CREATE OR REPLACE TRIGGER restrict_orders
BEFORE INSERT ON orders
FOR EACH ROW
BEGIN
DECLARE countOrders number;
set countOrders := SELECT count(contract) FROM orders WHERE :new:contract := old:contract AND (:old.status := 'PREPARING' OR :old.status := 'IN PROGRESS');
IF (countOrders :> 3)
THEN
RAISE_APPLICATION_ERROR (-20202, 'You have too much active orders.');
END IF;
END;
Quite a few errors; see if this helps.
Sample table:
SQL> select * From orders;
CONTRACT STATUS
---------- ---------
1 PREPARING
Trigger:
SQL> CREATE OR REPLACE TRIGGER restrict_orders
2 BEFORE INSERT ON orders
3 FOR EACH ROW
4 DECLARE
5 countOrders number;
6 BEGIN
7 SELECT count(contract)
8 INTO countOrders
9 FROM orders
10 WHERE contract = :new.contract
11 AND status IN ('PREPARING', 'IN PROGRESS');
12
13 IF countOrders > 3 THEN
14 RAISE_APPLICATION_ERROR (-20202, 'You have too many active orders.');
15 END IF;
16 END;
17 /
Trigger created.
Testing:
SQL> insert into orders (contract, status) values (1, 'PREPARING');
1 row created.
SQL> insert into orders (contract, status) values (1, 'PREPARING');
1 row created.
SQL> insert into orders (contract, status) values (1, 'PREPARING');
1 row created.
SQL> insert into orders (contract, status) values (1, 'PREPARING');
insert into orders (contract, status) values (1, 'PREPARING')
*
ERROR at line 1:
ORA-20202: You have too many active orders.
ORA-06512: at "SCOTT.RESTRICT_ORDERS", line 11
ORA-04088: error during execution of trigger 'SCOTT.RESTRICT_ORDERS'
Kind of works. However, note that it'll fail if you attempt to insert more than a single row at a time because table will be mutating (so you'd have to take another, more complex approach), but - if you'll insert just one row at a time, you're good:
SQL> insert into orders (contract, status)
2 select 1, 'PREPARING' from dual union all
3 select 2, 'IN PROGRESS' from dual;
insert into orders (contract, status)
*
ERROR at line 1:
ORA-04091: table SCOTT.ORDERS is mutating, trigger/function may not see it
ORA-06512: at "SCOTT.RESTRICT_ORDERS", line 4
ORA-04088: error during execution of trigger 'SCOTT.RESTRICT_ORDERS'
SQL>
You need to correct your syntax which should be -
CREATE OR REPLACE TRIGGER restrict_orders
BEFORE INSERT ON orders
FOR EACH ROW
DECLARE countOrders number;
BEGIN
SELECT count(contract)
INTO countOrders
FROM orders
WHERE :new.contract = :old.contract
AND :old.status IN ('PREPARING', 'IN PROGRESS');
IF (countOrders >= 3) THEN
RAISE_APPLICATION_ERROR (-20202, 'You have too much active orders.');
END IF;
END;

What does error 'identifier must be declared' means in PL/SQL?

The task is to write PL/SQL block for entering new employee throw the Oracle database user's dialog to insert data into the table.
I dont really understand what I am missing here:
SET SERVEROUTPUT ON
ACCEPT empno PROMPT 'Enter empno: '
ACCEPT ename PROMPT 'Enter ename: '
ACCEPT job PROMPT 'Enter job: '
ACCEPT mgr PROMPT 'Enter mgr: '
ACCEPT sal PROMPT 'Enter sal: '
ACCEPT deptno PROMPT 'Enter deptno: '
DECLARE
empn NUMBER := &empno;
ena VARCHAR(255) := &ename;
ejob VARCHAR(255) := &job;
emgr NUMBER := &mgr;
ehire DATE := Sysdate;
esal NUMBER := &sal;
ecomm NUMBER := null;
edeptno NUMBER := &deptno;
BEGIN
INSERT INTO EMP(EMPNO, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (empn, ena, ejob, emgr, ehire, esal, ecomm, edeptno);
END;
Error report:
Error report - ORA-06550: line 3, column 21: PLS-00201: identifier 'ANDREW' must be declared ORA-06550: line 3, column 5: PL/SQL: Item ignored ORA-06550: line 4, column 22: PLS-00201: identifier 'MANAGER' must be declared ORA-06550: line 4, column 6: PL/SQL: Item ignored ORA-06550: line 11, column 17: PL/SQL: ORA-00913: too many values ORA-06550: line 11, column 5: PL/SQL: SQL Statement ignored 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. *Action:
Could you explain, what are the mistakes in my code?
I tried the following:
SET SERVEROUTPUT ON
ACCEPT empno PROMPT 'Enter empno: '
ACCEPT ename PROMPT 'Enter ename: '
ACCEPT job PROMPT 'Enter job: '
ACCEPT mgr PROMPT 'Enter mgr: '
ACCEPT sal PROMPT 'Tneter sal: '
ACCEPT deptno PROMPT 'Enter deptno: '
DECLARE
empn NUMBER := '&empno';
ena VARCHAR(255) := '&ename';
ejob VARCHAR(255) := '&job';
emgr NUMBER := '&mgr';
ehire DATE := Sysdate;
esal NUMBER := '&sal';
ecomm NUMBER := null;
edeptno NUMBER := '&deptno;
BEGIN
INSERT INTO EMP(EMPNO, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (empn, ena, ejob, emgr, ehire, esal, ecomm, edeptno);
END;
Error:
Error report -
ORA-06550: line 9, column 19:
PLS-00103: Encountered the symbol "30;
BEGIN
INSERT INTO EMP(EMPNO, JOB, MGR, HIREDATE, SAL, CO" when expecting one of the following:
( - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current exists max min prior sql stddev
sum variance execute forall merge time timestamp interval
date <a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
The substitution variables are replaced using your input.
For example, becomes:
ena VARCHAR(255) := &ename;
ena VARCHAR(255) := ANDREW;
And here is the error. Single quotes are missing.
So correct would be:
ena VARCHAR(255) := '&ename';
You should also specify the data type and the format mask. For example:
ACCEPT esal NUMBER FORMAT '999.99'
ACCEPT hired DATE FORMAT 'dd/mm/yyyy'

Stored Procedure + Call Not working

My Stored Procedure compiles, however; when I try to call it i get the following error:
Encountered the symbol "IS" when expecting one of the following:
constant exception <an identifier>
<a double-quoted delimited-identifier> table long double ref
char time timestamp interval date binary national character
nchar
The symbol "IS" was ignored.
ORA-06550: line 2, column 48:
PLS-00103: Encountered the symbol "," when expecting one of the following:
:= ( ; not null range default character
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
My Stored Procedure is as follows:
create or replace procedure p_xml
(v_utc_offset in XML_HOURS_LOAD.UTCOFFSET%type
, v_data_date in XML_HOURS_LOAD.DATA_DATE%type
, v_data_type in XML_HOURS_LOAD.DATA_TYPE%type
, v_posted_value in XML_HOURS_LOAD.POSTEDVALUE%type
, v_utc_value in XML_HOURS_LOAD.UTCVALUE%type
, v_hour in XML_HOURS_LOAD.HOUR%type
, v_data_code in XML_HOURS_LOAD.DATA_CODE%type
)
AS
BEGIN
if v_utc_offset >= 4 THEN
INSERT INTO xml_hours_Load (UTCOffset, Data_date, Data_Type, PostedValue, UTCValue, Hour, Data_Code)
VALUES(v_utc_offset, v_data_date, v_data_type, v_posted_value, v_utc_value, v_hour, v_data_code);
COMMIT;
END IF;
END;
How I am calling it (and what is returning the error listed above) is as follows:
DECLARE
v_utc_offset is XML_HOURS_LOAD.UTCOFFSET%type,
v_data_date is XML_HOURS_LOAD.DATA_DATE%type,
v_data_type is XML_HOURS_LOAD.DATA_TYPE%type,
v_posted_value is XML_HOURS_LOAD.POSTEDVALUE%type,
v_utc_value is XML_HOURS_LOAD.UTCVALUE%type,
v_hour is XML_HOURS_LOAD.HOUR%type,
v_data_code is XML_HOURS_LOAD.DATA_CODE%type;
CURSOR cXmlHoursLoadCursor is (SELECT utcoffset, data_date, data_type, postedvalue, utcvalue, hour, data_code
from xml_hours_load);
BEGIN
FOR v in cXmlHoursLoadCursor LOOP
p_xml(v.utcoffset, v.data_date, v.data_type, v.postedvalue, v.utcvalue, v.hour, v.data_code);
COMMIT;
END LOOP;
END;
Thanks in Advance!
In your anonymous block, the CURSOR is the only variable you should declare using the IS keyword. Remove it from the others.
DECLARE
v_utc_offset XML_HOURS_LOAD.UTCOFFSET%type;
v_data_date XML_HOURS_LOAD.DATA_DATE%type;
v_data_type XML_HOURS_LOAD.DATA_TYPE%type;
v_posted_value XML_HOURS_LOAD.POSTEDVALUE%type;
v_utc_value XML_HOURS_LOAD.UTCVALUE%type;
v_hour XML_HOURS_LOAD.HOUR%type;
v_data_code XML_HOURS_LOAD.DATA_CODE%type;
CURSOR cXmlHoursLoadCursor is (SELECT utcoffset, data_date, data_type, postedvalue, utcvalue, hour, data_code
from xml_hours_load);
BEGIN
FOR v in cXmlHoursLoadCursor LOOP
p_xml(v.utcoffset, v.data_date, v.data_type, v.postedvalue, v.utcvalue, v.hour, v.data_code);
COMMIT;
END LOOP;
END;

PLSQL - Error in associative array

Im trying to delete a set of tables and afterwards I want to recreate them using as select from. For couriousity I wanted to do this with an associative array. Unfortunately something is messed up, several errors appear and I can't find the reasons. This is the code:
DECLARE
TYPE t_tbl
IS
TABLE OF VARCHAR(100) INDEX BY VARCHAR2(100);
L_Tbl T_Tbl;
l_key VARCHAR2(100);
BEGIN
l_tbl('tableA') := 'table1';
l_tbl('tableB') := 'table2';
L_Tbl('tableC') := 'table3';
l_tbl('tableD') := 'table4';
l_key := l_tbl.first;
LOOP
BEGIN
EXIT WHEN L_Key IS NULL;
Dbms_Output.Put_Line('Dropping TABLE '|| L_Key ||);
EXECUTE Immediate 'DROP TABLE ' || L_Key;
dbms_output.put_line(l_key ||' '|| l_tbl(l_key));
-- Catch exception if table does not exist
EXCEPTION
WHEN OTHERS THEN
IF SQLCODE != -942 THEN
Raise;
END IF;
EXECUTE IMMEDIATE 'create table schema1.' ||l_key||' as select * from schema2.'||l_tbl(l_key)||;
l_key := l_tbl.next(l_key);
END LOOP;
End;
END;
I get these errors:
ORA-06550: line 17, column 56:
PLS-00103: Encountered the symbol ")" when expecting one of the following:
( - + case mod new null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current max min prior sql stddev sum
variance execute forall merge time timestamp interval date
<a string literal with character set specification>
<a number> <a single-quoted SQL string> pipe
<an alternatively-quoted string literal with character set specification>
<an alternatively-quoted SQL
ORA-06550: line 26, column 102:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
( - + case mod new null <an identifier>
<a double-quoted delimited-identifier> <a bind variable>
continue avg count current max min prior sql stddev su
ORA-06550: line 29, column 6:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
loop
The symbol "loop" was substituted for ";" to continue.
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Could someone give me a hint please? Thank you in advance!
You have some unterminated append operations || on lines:
Dbms_Output.Put_Line('Dropping TABLE '|| L_Key ||);
And
EXECUTE IMMEDIATE 'create table schema1.' ||l_key||' as select * from schema2.'||l_tbl(l_key)||;
Get rid of the || at the end.
Also the way you are using LOOP is incorrect. Refer example:
while elem is not null loop
dbms_output.put_line(elem || ': ' || var_assoc_varchar(elem));
elem := var_assoc_varchar.next(elem);
end loop;
Remove || at the end of the line in line 17 and line 25.
And also ending loop before ending the block begin....end. get begin before loop or get end before end loop.
l_key := l_tbl.next(l_key);
END LOOP;
END;

What is the meaning of "(." and ".)" in PL/SQL?

I have found this PL/SQL code but I can't find in Oracle documentation to be valid:
CREATE OR REPLACE PROCEDURE hard_priv AS
BEGIN
HTP.htmlOpen;
HTP.headOpen;
HTP.title (.Account Information.);
HTP.headClose;
HTP.bodyOpen;
HTP.br;
HTP.print('User ID: ' ||
OWA_SEC.get_user_id || '');
HTP.print('User Password: ' ||
OWA_SEC.get_password || '');
HTP.br;
HTP.bodyClose;
HTP.htmlClose;
END hard_priv;
END uu_hr_pkg;
"(." and ".)" is not PLSQL syntax.
So it cannot compile.
This simple:
begin
dbms_output.put_line('this is the right syntax');
dbms_output.put_line(.this_dont_work.);
end;
/
Gives a compilation error like that:
SQL> #a
dbms_output.put_line(.this_dont_work.);
*
ERROR at line 3:
ORA-06550: line 3, column 26:
PLS-00103: Encountered the symbol "." when expecting one of the following:
( ) - + case mod new not null <an identifier>
<a double-quoted delimited-identifier> <a bind variable> table continue avg count current exists max min prior sql
stddev sum variance execute multiset the both leading
trailing forall merge year month day hour minute second
timezone_hour timezone_minute timezone_region timezone_abbr
time timestamp interval date
In the real world, you must replace them with '; your thing should be:
CREATE OR REPLACE PROCEDURE hard_priv AS
BEGIN
HTP.htmlOpen;
HTP.headOpen;
HTP.title ('Account Information');
HTP.headClose;
....

Resources