Stored Procedure Error (column ambiguously defined) - oracle

Getting the following error for this line Create a stored procedure that takes as its argument as industryid
CREATE OR REPLACE PROCEDURE businesses (industryid INDUSTRY.INDUSTRYID%TYPE) AS
CURSOR businessloop IS
select tx.UNIONTITLE,b.ABNNUMBER,b.BUSINESSNAME
from business b INNER JOIN business_industry bi
on
b.ABNNUMBER = bi.ABNNUMBER
INNER JOIN industry ind
on
bi.INDUSTRYID = ind.INDUSTRYID
INNER JOIN trade_union tx
on
ind.UNIONID = tx.UNIONID
where
INDUSTRY.INDUSTRYID = industryid;
BEGIN
FOR ptr IN businessloop LOOP
DBMS_OUTPUT.PUT_LINE(ptr.UNIONTITLE);
DBMS_OUTPUT.PUT_LINE(ptr.ABNNUMBER);
DBMS_OUTPUT.PUT_LINE(ptr.BUSINESSNAME);
DBMS_OUTPUT.PUT_LINE('---------------------------');
END LOOP;
end businesses;
/
Execute businesses(6);
my output looks like this
Errors: PROCEDURE BUSINESSES
Line/Col: 5/1 PL/SQL: SQL Statement ignored
Line/Col: 16/23 PL/SQL: ORA-00918: column ambiguously defined
Line/Col: 26/1 PL/SQL: Statement ignored
Line/Col: 26/22 PLS-00364: loop index variable 'PTR' use is invalid
Line/Col: 27/1 PL/SQL: Statement ignored
Line/Col: 27/22 PLS-00364: loop index variable 'PTR' use is invalid
Line/Col: 28/1 PL/SQL: Statement ignored
Line/Col: 28/22 PLS-00364: loop index variable 'PTR' use is invalid
ORA-06550: line 1, column 7:
PLS-00905: object SQL_PQETEGYQDKCHNVXHUMIWRPLSE.BUSINESSES is invalid
I think error comes with this line
INDUSTRY.INDUSTRYID = industryid;

Answered in comments:
I think error comes with this line You're probably right. Rename procedure's parameter and eliminate names interference. – Akina 2 hours ago
thanks, man that's the reason, #Akina – sandun wijerathne Jerry 2 hours ago

Answer
CREATE OR REPLACE PROCEDURE businesses (industryidx INDUSTRY.INDUSTRYID%TYPE) AS
CURSOR businessloop IS
select tx.UNIONTITLE,b.ABNNUMBER,b.BUSINESSNAME
from business b INNER JOIN business_industry bi
on
b.ABNNUMBER = bi.ABNNUMBER
INNER JOIN industry ind
on
bi.INDUSTRYID = ind.INDUSTRYID
INNER JOIN trade_union tx
on
ind.UNIONID = tx.UNIONID
where
ind.INDUSTRYID = industryidx;
BEGIN
FOR ptr IN businessloop LOOP
DBMS_OUTPUT.PUT_LINE(ptr.UNIONTITLE);
DBMS_OUTPUT.PUT_LINE(ptr.ABNNUMBER);
DBMS_OUTPUT.PUT_LINE(ptr.BUSINESSNAME);
DBMS_OUTPUT.PUT_LINE('---------------------------');
END LOOP;
end businesses;
/
Execute businesses(6);

Related

Need help understanding Cursor for loop

I am trying to write a code for every stock value that is $75 or more
add a "*" in the STK_FLAG column. my error repots are: Error report -
ORA-06550: line 15, column 21: PLS-00201: identifier 'STK_FLG' must be
declared ORA-06550: line 15, column 5: PL/SQL: SQL Statement ignored
ORA-06550: line 23, column 7: PL/SQL: ORA-00904: "STK_FLG": invalid
identifier ORA-06550: line 17, column 5: PL/SQL: SQL Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Blockquote
SET SERVEROUTPUT ON
DECLARE
CURSOR CURR
IS
SELECT STK_FLAG
FROM MM_MOVIE
WHERE MOVIE_VALUE * MOVIE_QTY >= 75
FOR UPDATE;
BEGIN
OPEN CURR;
LOOP
FETCH CURR INTO STK_FLG;
UPDATE
MM_MOVIE
SET
STK_FLG= '*'
WHERE
CURRENT OF CURR;
EXIT
WHEN CURR%notfound;
END LOOP;
Commit;
CLOSE CURR;
END;
/
You didn't declare a cursor variable (so there's nowhere you can put values returned by the cursor). Don't name it as column name; use a prefix, such as v_ or l_ or whichever you want.
Furthermore, in UPDATE you referenced a non-existent column. Cursor suggests its name is stk_flag, not stk_flg
Therefore, code that might be OK is
DECLARE
CURSOR curr IS
SELECT stk_flag
FROM mm_movie
WHERE movie_value * movie_qty >= 75
FOR UPDATE;
l_stk_flag mm_movie.stk_flag%TYPE; --> this
BEGIN
OPEN curr;
LOOP
FETCH curr INTO l_stk_flag;
EXIT WHEN curr%NOTFOUND;
UPDATE mm_movie
SET stk_flag = '*' --> this
WHERE CURRENT OF curr;
END LOOP;
COMMIT;
CLOSE curr;
END;
/
Why use a pl/sql anonymous block? Even if there is an "external" requirement for the functionality wrapped into pl/sql why use a cursor and loop? Using code that might be OK (from #Littlefoot) you retrieve a single column meeting your condition, iterate the resulting record set fetching that column but otherwise do nothing with it, and update a single row on every iteration of the loop with a literal value. SQL is designed for processing entire sets of rows at a time. Your processing can be done in a single update statement. Assuming there is an external requirement for a pl/sql block your code reduces to:
BEGIN
UPDATE mm_movie
SET stk_flag = '*'
WHERE movie_value * movie_qty >= 75;
COMMIT;
END;
Take away: When working with SQL stop thinking in terms of iterating (loops). Instead think of the commonality (set) of all objects to be processed. A different way of looking at problems and their corresponding solutions to be sure. Getting used to thinking that way will take some time, but in the long run your SQL and procedures will greatly improve because of it. Both in performance and clarity.

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

Apex button and procedure

Im trying to create button in Apex which execute given procedure. As input values I gave two date fields called Poczatek and Koniec. The button should execute this procedure on submit. It perfectly works in Oracle, but throw a lot of errors in Apex.
set serveroutput on
create or replace procedure KORELACJA(:Poczatek, :Koniec)
IS
miasto VARCHAR(25);
korelacja NUMBER;
cursor c1 is
SELECT TEMP.nazwa, corr(TEMP.temperatura, WILGOTNOSC.wilg)
FROM TEMP INNER JOIN WILGOTNOSC
on TEMP.nazwa = WILGOTNOSC.nazwa
and TEMP.data = WILGOTNOSC.data
WHERE TEMP.data between to_date(:Poczatek, 'YYYY-MM-DD') and to_date(:Koniec, 'YYYY-MM-DD')
GROUP BY TEMP.nazwa;
BEGIN
DBMS_OUTPUT.put_line(RPAD('Miasto',10)||RPAD('Korelacja',10));
open c1;
FOR i IN 1..6
LOOP
commit;
fetch c1 into miasto, korelacja;
DBMS_OUTPUT.put_line(RPAD(miasto,10)||RPAD(korelacja,10));
END LOOP;
close c1;
END KORELACJA;
/
Errors look like this:
1 error has occurred
ORA-06550: line 2, column 5: PL/SQL: ORA-00922: missing or invalid option
ORA-06550: line 2, column 1: PL/SQL: SQL Statement ignored ORA-06550: line 6,
column 11: PLS-00103: Encountered the symbol "NUMBER" when expecting one of the
following: := . ( # % ; ORA-06550: line 9, column 18: PLS-00103: Encountered the symbol "JOIN" when
expecting one of the following: , ; for group having intersect minus order start
union where connect
Anyone knows the solution?
I'd suggest you to leave the procedure in the database; call it from Apex.
As you said that it works OK, I'm not going to examine the code. Just modify the first line:
create or replace procedure KORELACJA(par_Poczatek in date,
par_Koniec in date)
is ...
Then, in Apex process, call the procedure as
korelacja(:p1_poczatek, :p2_koniec);
Note that you might need to apply TO_DATE function to those items, using appropriate format mask, such as
korelacja(to_date(:p1_poczatek, 'dd.mm.yyyy',
to_date(:p1_koniec , 'dd.mm.yyyy');
If you insist on keeping the procedure in Apex' process (I wouldn't recommend it), the you don't need CREATE PROCEDURE but an anonymous PL/SQL block. It won't accept any parameters - use Apex items directly.
declare
miasto VARCHAR(25);
korelacja NUMBER;
cursor ...
WHERE TEMP.data between to_date(:p1_Poczatek, 'YYYY-MM-DD') ...
begin
...
end;

Oracle pl/sql - Use associative array with user created record

I'm trying to use an associative array with the element type of a user defined record. This array is to print the first name, last name, and grade of a student.
SET SERVEROUTPUT ON
DECLARE
TYPE studentRec IS RECORD (
STUDENT_ID studentdb.student.student_id%TYPE,
FIRST_NAME STUDENTDB.STUDENT.FIRST_NAME%TYPE,
LAST_NAME STUDENTDB.STUDENT.LAST_NAME%TYPE,
GRADE STUDENTDB.GRADE.NUMERIC_GRADE%TYPE
);
CURSOR studentCursor IS
SELECT STUDENT.STUDENT_ID, STUDENT.FIRST_NAME, STUDENT.LAST_NAME, AVG(GRADE.NUMERIC_GRADE) AS GRADE
FROM STUDENTDB.STUDENT
INNER JOIN STUDENTDB.GRADE
ON STUDENTDB.STUDENT.STUDENT_ID = STUDENTDB.GRADE.STUDENT_ID
GROUP BY STUDENT.STUDENT_ID, STUDENT.FIRST_NAME, STUDENT.LAST_NAME ;
sr studentRec;
TYPE studentArray IS TABLE OF studentRec INDEX BY PLS_INTEGER;
vars studentArray;
BEGIN
FOR rec IN studentCursor LOOP
vars(rec.STUDENT_ID) := rec.FIRST_NAME || ' ' || rec.LAST_NAME || ' has grade ' || rec.GRADE;
END LOOP;
FOR ind IN vars.FIRST .. vars.LAST LOOP
DBMS_OUTPUT.PUT_LINE(vars(ind));
END LOOP;
END;
This throws:
Error report - ORA-06550: line 27, column 27: PLS-00382: expression is
of wrong type ORA-06550: line 27, column 3: PL/SQL: Statement ignored
ORA-06550: line 33, column 1: PLS-00306: wrong number or types of
arguments in call to 'PUT_LINE' ORA-06550: line 33, column 1: PL/SQL:
Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
You don't need a RECORD declaration here, although you could use it if you know it. It is better to use CURSOR%ROWTYPE. syntax as shown. There is also no need of associative array, as your indexes are going to be numbers anyway.
Also, instead of looping through the CURSOR, you could use BULK COLLECT INTO.
You cannot directly pass vars(ind) to .PUT_LINE() . It should refer to specific column names.
SET serveroutput ON
DECLARE
CURSOR studentcursor IS
SELECT student.student_id,
student.first_name,
student.last_name,
AVG(grade.numeric_grade) AS GRADE
FROM studentdb.student
inner join studentdb.grade
ON studentdb.student.student_id =
studentdb.grade.student_id
GROUP BY student.student_id,
student.first_name,
student.last_name;
TYPE studentarray
IS TABLE OF studentcursor%ROWTYPE;
vars STUDENTARRAY;
BEGIN
OPEN studentcursor;
FETCH studentcursor BULK COLLECT INTO vars;
FOR ind IN vars.first .. vars.last LOOP
dbms_output.put_line(vars(ind).student_id
||','
|| vars(ind).first_name
||','
||vars(ind).last_name
||','
|| vars(ind).grade);
END LOOP;
END;

PL SQL Stored Procedure for new Transaction and order

I'm giving a small snippet of my code but I 'm receiving the below error when trying to create a new order for a stored Oracle pl sql procedure.
line 83 is the insert statement in the code and line 84 is in the insert part of the statement.
83/5 PL/SQL: SQL Statement ignored
84/47 PL/SQL: ORA-00984: column not allowed here
BEGIN
--Initializing values for variables
x_rowcount := 0;
x_stockonhand := 0;
Totaldue := 0;
--Total due calculation
--(price of phone*quantity + shipping cost)*1.06 (assuming 6% sales tax)
Totaldue := (((i_price * c_p_qty) + i_shipping_cost) * 1.06);
SAVEPOINT start_transaction; -- mark a savepoint
--INSERT a new record into order table.
INSERT INTO orders(o_id,c_id,p_id,s_id,order_date,o_qty,order_total,card_type,cc_number,exp_date,shipping_status)
VALUES (orders_seq.nextval, c_c_id,c_p_id,s_id,sysdate,c_p_qty,Totaldue,c_card_type,c_cc_number,c_exp_date,'Not shipped yet');
Check your declaration section. Usually this error appears when you make a typo in variable name or variable not declared. For example:
SQL> create table tmp (id number, str varchar2(100));
Table created.
SQL> declare
a number;
begin
insert into tmp (id, str)
values (a, a1);
end;
/
values (a, a1);
*
ERROR at line 5:
ORA-06550: line 5, column 14:
PL/SQL: ORA-00984: column not allowed here
ORA-06550: line 4, column 3:
PL/SQL: SQL Statement ignored
The error is because one or more of the values in your VALUES(...,...) section is invalid.
I would suggest checking each one to see that they are valid. For example, is c_c_id declared and given a value somewhere else in the code? If not, this is likely your problem. Each one needs to be declared and given a value before it can be put in the VALUES(...,...) section of the INSERT statement.
INSERT INTO orders(o_id,c_id,p_id,s_id,order_date,o_qty,order_total,card_type,cc_number,exp_date,shipping_status)
VALUES (orders_seq.nextval, c_c_id,c_p_id,s_id,sysdate,c_p_qty,Totaldue,c_card_type,c_cc_number,c_exp_date,'Not shipped yet');

Resources