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

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'

Related

PL/SQL Block in oracle11g

I have to the following question but what I have tried keeps giving me an error.
Create a PL/SQL query to display the product name, product price and delivery description. Only display the records where the difference between the despatch date and delivery date is greater than three days. In your query also determine whether the product is a premium or non-premium product.
This is what I have attempted.
set SERVEROUTPUT on;
DECLARE
p_product VARCHAR2(50);
p_price VARCHAR2(50);
d_description VARCHAR2(50);
d_days NUMBER(3.0);
p_productcat VARCHAR2(50);
cursor INFO IS
select p.Product, p.Price, d."Description", d.despatchdate || d.deliverydate as "Delivery Days"
from product p, delivery d
where d.deliverydate ('dd')- d.despatchdate('dd') > 3;
begin
open INFO;
loop
if (p_price > 15000) then
p_productcat:='Premium Product';
else
p_productcat:='Non Premium Product';
end if;
exit when INFO%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('PRODUCT:'|| p_product||chr(30)||'PRICE:'||p_price||chr(13)||'DESCRIPTION:'||
d_description || chr(50) || 'DELIVERY DAYS:' || d_days || chr(13) || 'PRODUCT CATEGORY:' ||
p_productcat);
DBMS_OUTPUT.PUT_LINE('----------------------------------------------');
end loop;
close info;
end;
The error is:
Error starting at line : 254 in command
Error report -
ORA-06550: line 10, column 30:
PL/SQL: ORA-00904: "D"."DESPATCHDATE": invalid identifier
ORA-06550: line 8, column 1:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Ah! Mystery! I love that! But - not that much in coding. Saying that there are errors - which errors?
Until you respond, here's what looks suspicious:
d."Description" - unless column is created using double quotes, this won't work. Use d.description instead
don't compare days in a month (unless you're sure that those dates will always be in the same month). Use WHERE d.deliverydate - d.despatchdate > 3. Or, if you insist, apply the TO_CHAR function: WHERE to_char(d.deliverydate, 'dd') - to_char(d.despatchdate, 'dd') > 3

I don't understand what is the problem in my store procedure

Create or replace PROCEDURE SSp_EmpHoursInfo
(p_EHrsInfo OUT SYS_REFCURSOR)
AS
BEGIN
OPEN p_EHrsInfo FOR
Select
a.personid, a.first_name, a.last_name,c.hoursworked,d.carecentername, c.break
from person a
join employee b on a.personid = b.empersonid
join employee_assigned_care_center c on b.empersonid = c.empersonid
join care_center d on c.empersonid = d.carecenterid
where hoursworked> 10;
END SSp_EmpHoursInfo;
Everytime I am trying to call the store procedure it is giving me this error msg:
Error starting at line : 225 in command -
BEGIN SSp_EmpHoursInfo (hoursworked> 10); END;
Error report -
ORA-06550: line 1, column 3:
PLS-00201: identifier 'HOURSWORKED' must be declared
ORA-06550: line 1, column 52:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
The problem is very obvious.
BEGIN SSp_EmpHoursInfo (hoursworked> 10); END; is not the proper way of calling it.
The procedure parameter must be the sys_refcursor.
You must use:
DECLARE
OUTPUT_CUR SYS_REFCURSOR;
BEGIN
SSp_EmpHoursInfo (OUTPUT_CUR );
-- USE CURSOR ACCORDINGLY
END;
/

BULK Collect into misleading error messages for ORA-00913 & ORA-00947

desc book_data;
Name Null Type
---------- ---- ------------
BOOK_NAME VARCHAR2(50)
BOOK_PRICE NUMBER
BOOK_SSN VARCHAR2(50)
DECLARE
TYPE book_rec is record(
book_name varchar2(50),
book_price number,
book_ssn varchar2(50)
);
type book_tbl_type is table of book_rec;
book_tbl1 book_tbl_type := book_tbl_type();
BEGIN
SELECT BOOK_NAME, BOOK_PRICE/*,book_ssn,1*/ BULK COLLECT INTO book_tbl1 FROM book_data;
DBMS_OUTPUT.put_line(book_tbl1(1).book_name);
END;
Error report -
ORA-06550: line 11, column 75:
PL/SQL: ORA-00913: too many values
ORA-06550: line 11, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Question : Here we are inserting two columns into three column collection table Then We Should have got "ORA-00947: not enough values" error.But We are getting "ORA-00913: too many values". Why ?
DECLARE
TYPE book_rec is record(
book_name varchar2(50),
book_price number,
book_ssn varchar2(50)
);
type book_tbl_type is table of book_rec;
book_tbl1 book_tbl_type := book_tbl_type();
BEGIN
SELECT BOOK_NAME, BOOK_PRICE,book_ssn,1 BULK COLLECT INTO book_tbl1 FROM book_data;
DBMS_OUTPUT.put_line(book_tbl1(1).book_name);
END;
Error report -
ORA-06550: line 11, column 71:
PL/SQL: ORA-00947: not enough values
ORA-06550: line 11, column 3:
PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Question : Here we are inserting four columns into three column collection table . Then We Sould have got "ORA-00913: too many values" error .
But We are getting "ORA-00947: not enough values". Why ?
ORA-00913 too many values
Cause: The SQL statement requires two sets of values equal in number. This error occurs when the second set contains more items than the first set. For example, the subquery in a WHERE or HAVING clause may return too many columns, or a VALUES or SELECT clause may return more columns than are listed in the INSERT.
Action: Check the number of items in each set and change the SQL statement to make them equal.
In case of BULK COLLECT it seems that the error message refers to the number of columns in collection table, not to the number of selected columns..
To avoid similar problems you can use %ROWTYPE, something like that:
DECLARE
type book_tbl_type is table of book_data%ROWTYPE;
book_tbl1 book_tbl_type := book_tbl_type();
BEGIN
SELECT b.* BULK COLLECT INTO book_tbl1 FROM book_data b;
END;
/

Error calling stored procedure from PHP

I have a problem with this code in Oracle:
create or replace procedure InsertarEntertNotica (IDSUBTOPIC out varchar,
TEXT out varchar,IMAGE out varchar,STADE out varchar,TITT out varchar)
is
idS varchar2(3) := IDSUBTOPIC;
txt varchar2(4000) := TEXT;
img varchar2(100) := IMAGE;
st varchar2(2) := STADE;
fech varchar2(30);
tit varchar2(300) := TITT;
hor date;
begin
SELECT TO_CHAR(SYSDATE,'DD/MM/YY') into fech FROM DUAL;
SELECT SYSDATE into hor FROM DUAL;
insert into ENTERTAIMENT (IDSUBTEMA,TEXTO,IMAGEN,ESTADO,FECHA,TITULO,HORA)
values (idS,txt,img,st,fech,tit,hor);
end;
When I create this SP, I have not problem, but when I execute it I have this problem
Error starting at line : 377 in command -
execute InsertarEntertNotica('ET','Texto de la Noticia Proc','','No','Noticia con Procedimiento')
Error report -
ORA-06550: line 1, column 28:
PLS-00363: expression 'ET' cannot be used as an assignment target
ORA-06550: line 1, column 33:
PLS-00363: expression 'Texto de la Noticia Proc' cannot be used as an assignment target
ORA-06550: line 1, column 60:
PLS-00363: expression '<null>' cannot be used as an assignment target
ORA-06550: line 1, column 63:
PLS-00363: expression 'No' cannot be used as an assignment target
ORA-06550: line 1, column 68:
PLS-00363: expression 'Noticia con Procedimiento' cannot be used as an assignment target
ORA-06550: line 1, column 7:
You've declared all your formal parameters as OUT, which means when you call the procedure you must pass updatable variables, not fixed string values. The documentation shows how IN/OUT works.
You can just change them to IN. You also don't need any of the local variables:
create or replace procedure InsertarEntertNotica (IDSUBTOPIC in varchar,
TEXT in varchar,IMAGE in varchar,STADE in varchar,TITT in varchar)
is
begin
insert into ENTERTAIMENT (IDSUBTEMA, TEXTO, IMAGEN, ESTADO, FECHA, TITULO, HORA)
values (IDSUBTOPIC, TEXT, IMAGE, STADE, TO_CHAR(SYSDATE,'DD/MM/YY'),
TITT, SYSDATE);
end;
If you are going to have local variables then names that distinguish from the parameter names would be good. It's common to use a prefix to distinguish, e.g. p_text for the parameter and l_text for the local variable.
Using TO_CHAR(SYSDATE,'DD/MM/YY') looks wrong for a couple of reasons. Two digit years can cause unexpected results, as well as the infamous Y2K problems. If FECHA is a DATE column rather than VARCHAR2(8), as it should be, then you are implicitly converting that string back to a date using the session NLS settings - which is dangerous, and will only work at all if the session happens to also be DD/MM/YY. If you're really trying to store today's date with the time as midnight then you should use TRUNC(SYSDATE) instead. Although not sure why you'd store that as a separate column to HORA anyway.

array in oracle block

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);

Resources