SQL Invalid Identifier when using bind variable - sql

Using my anonymous block I have written below, the bind variable is giving me the error: I've pasted a picture of the table below.
edit: ETHI1022 is the input I'm giving for the CORID
v_corid CHAR(8) := ETHI1022;
*
ERROR at line 3:
ORA-06550: line 3, column 24:
PLS-00201: identifier 'ETHI1022' must be declared
ORA-06550: line 0, column 0:
PL/SQL: Compilation unit analysis terminated
I realize my inner join is most likely messed up like no other. I'm trying to learn this stuff and am having a very hard time learning how taking values from the select statement and placing them into the variables in the declare section works.
DECLARE
v_marstuid MARKS.STUID%TYPE;
v_corid CHAR(8) := &corid;
v_avgmark NUMBER(2);
v_maxmark NUMBER(2);
v_minmark NUMBER(2);
v_cordesc VARCHAR2(255);
ex_CourseNotFound EXCEPTION;
BEGIN
SELECT Count(M.stuid),
M.corid,
Avg(M.mark),
Max(M.mark),
Min(M.mark),
C.descript
INTO v_marstuid, v_corid, v_avgmark, v_maxmark,
v_minmark, v_cordesc
FROM marks M
inner join courses C
ON M.corid = C.corid
WHERE C.corid = v_corid;
dbms_output.Put_line (v_corid
|| ' - '
|| v_cordesc);
dbms_output.Put_line ('Course Stats: ');
dbms_output.Put_line ('Number of students: '
|| v_marstuid);
dbms_output.Put_line ('Average: '
|| v_avgmark);
dbms_output.Put_line ('Marks Range: ');
dbms_output.Put_line ('High: '
|| v_maxmark);
dbms_output.Put_line ('Low: '
|| v_minmark);
EXCEPTION
WHEN ex_CourseNotFound THEN
DBMS_OUTPUT.PUT_LINE(v_corcode || ' Does not exist.');
END;
/
[Table used]

Instead of ETHI1022 it should be 'ETHI1022'. Your inner join is fine. From where you are getting value of corid. Make it of type varchar/string or something like that.
Or you might try v_corid CHAR(8) := ''''||&corid||'''';

Related

PL/SQL: Cursor doubles the last record from the table

I created the following PL/SQL anonymous block. The cursor below retrieves data from the select statement:
select mod_benutzer, count(*)
from dok_auspraegung
where parent_objekt_id = 1093
group by mod_benutzer;
This statement displays exactly two records:
DDMS_USER | 8
HU2MAMU | 14
But when I want to display these two records by cursor, it displays "HU2MAMU|14" two times like below:
Modifications:
DDMS_USER, 8x
HU2MAMU, 14x
HU2MAMU, 14x
declare
my_exception_1 exception;
var_parent_objekt_id dok_auspraegung.parent_objekt_id%TYPE := 1093;
var_date varchar(30);
var_mod_benutzer varchar2(10);
var_benutzer_modifs number;
cursor cursor_dok_auspraegung
is select mod_benutzer, count(*) from dok_auspraegung
where parent_objekt_id = 10935797565
group by mod_benutzer;
begin
select distinct to_char(mod_datum,'YYYY-MON-DD') into var_date from dok_auspraegung where parent_objekt_id = var_parent_objekt_id;
IF var_date is not null THEN
dbms_output.put_line('Parent Object ID' || ': ' || var_parent_objekt_id);
dbms_output.put_line('Date: ' || ' ' || var_date);
ELSE RAISE my_exception_1;
END IF;
open cursor_dok_auspraegung;
dbms_output.put_line('Modifications:');
loop
fetch cursor_dok_auspraegung into var_mod_benutzer, var_benutzer_modifs;
dbms_output.put(var_mod_benutzer);
dbms_output.put_line(', ' || var_benutzer_modifs || 'x');
exit when cursor_dok_auspraegung%notfound;
end loop;
dbms_output.put_line(cursor_dok_auspraegung%rowcount);
close cursor_dok_auspraegung;
exception
when NO_DATA_FOUND then
dbms_output.put_line('Parent Object ID not found!');
when my_exception_1 then
dbms_output.put_line('');
end;
What is the reason of that?
Because exiting from the cursor occurs after printing the value of the variables in the current case, this repeats the last value to be printed. So, it should occur before printing as follows
loop
fetch cursor_dok_auspraegung into var_mod_benutzer, var_benutzer_modifs;
exit when cursor_dok_auspraegung%notfound;
dbms_output.put(var_mod_benutzer);
dbms_output.put_line(', ' || var_benutzer_modifs || 'x');
end loop;

Why am i getting this: PLSQL String length constraint Error

i have being working on this code for a while now and have tried everything i can think of.
This is the code block:
CREATE OR REPLACE PROCEDURE ADD_LOCATION_TO_DB (ploccode VARCHAR2, pminqty
NUMBER, pmaxqty NUMBER)AS
Err_Locode_Length EXCEPTION;
Err_Minqty_Range EXCEPTION;
Err_Maxqty_Range EXCEPTION;
Err_Maxqty_Greater_Minqty EXCEPTION;
BEGIN
IF LENGTH(ploccode) != 5 THEN
RAISE Err_Locode_Length;
ELSE IF pminqty > 10 OR pminqty < 0 THEN
RAISE Err_Minqty_Range;
ELSE IF pmaxqty > 10 OR pmaxqty < 0 THEN
RAISE Err_Maxqty_Range;
ELSE IF pminqty > pmaxqty THEN
RAISE Err_Maxqty_Greater_Minqty;
END IF;
END IF;
END IF;
END IF;
INSERT INTO LOCATION
VALUES (ploccode, pminqty, pmaxqty);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
RAISE_APPLICATION_ERROR(-20081,'Duplicate Location ID');
WHEN Err_Locode_Length THEN
RAISE_APPLICATION_ERROR(-20082,'Location Code Lenght invalid');
WHEN Err_Minqty_Range THEN
RAISE_APPLICATION_ERROR(-20083,'Minium Qty is out of range');
WHEN Err_Maxqty_Range THEN
RAISE_APPLICATION_ERROR(-20084,'Maximum Qty is out of range');
WHEN Err_Maxqty_Greater_Minqty THEN
RAISE_APPLICATION_ERROR(-20086,'Minium Qty is Lager than Maximum Qty');
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000,'Use Value of SQLERRM');
END;
/
CREATE OR REPLACE PROCEDURE ADD_LOCATION_VIASQLDEV AS
Dis_Msg VARCHAR2;
ploccode VARCHAR2;
pminqty NUMBER;
pmaxqty NUMBER;
BEGIN
dbms_output.put_line('--------------------------------------------------');
dbms_output.put_line('Adding location LocCode: ' || ploccode || ' MinQty: ' || pminqty || 'MaxQty' || pmaxqty);
ADD_LOCATION_TO_DB(ploccode, pminqty, pmaxqty);
dbms_output.put_line(Dis_Msg);
END;
/
When i run this set of procedures i get an error in the compiler stating:
Error(1,13): PLS-00215: String length constraints must be in range (1 .. 32767)
Error(2,14): PLS-00215: String length constraints must be in range (1 .. 32767)
I have tried adding constraints to the code that calls the main Procedure:
CREATE OR REPLACE PROCEDURE ADD_LOCATION_VIASQLDEV AS
Dis_Msg VARCHAR2(40);
ploccode VARCHAR2(5);
pminqty NUMBER(2);
pmaxqty NUMBER(2);
BEGIN
dbms_output.put_line('--------------------------------------------------');
dbms_output.put_line('Adding location LocCode: ' || ploccode || ' MinQty: ' || pminqty || 'MaxQty' || pmaxqty);
ADD_LOCATION_TO_DB(ploccode, pminqty, pmaxqty);
dbms_output.put_line(Dis_Msg);
END;
/
Adding these constrains does remove the errors with the compiler however i still revive errors when executing this testing code:
Error starting at line : 48 in command -
begin
dbms_output.put_line('Student ID: 1234567');
dbms_output.put_line('==========PART 3 TEST LOCATIONS==========================');
ADD_LOCATION_VIASQLDEV ('AF201',1,2);
ADD_LOCATION_VIASQLDEV('AF202',-3,4);
ADD_LOCATION_VIASQLDEV ('AF203',5,1);
ADD_LOCATION_VIASQLDEV ('AF204',6,7000);
ADD_LOCATION_VIASQLDEV ('AF20111',8,9);
end;
Error report -
ORA-06550: line 4, column 1:
PLS-00306: wrong number or types of arguments in call to 'ADD_LOCATION_VIASQLDEV'
ORA-06550: line 4, column 1:
PL/SQL: Statement ignored
ORA-06550: line 5, column 1:
PLS-00306: wrong number or types of arguments in call to 'ADD_LOCATION_VIASQLDEV'
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
ORA-06550: line 6, column 1:
PLS-00306: wrong number or types of arguments in call to 'ADD_LOCATION_VIASQLDEV'
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
ORA-06550: line 7, column 1:
PLS-00306: wrong number or types of arguments in call to 'ADD_LOCATION_VIASQLDEV'
ORA-06550: line 7, column 1:
PL/SQL: Statement ignored
ORA-06550: line 8, column 1:
PLS-00306: wrong number or types of arguments in call to 'ADD_LOCATION_VIASQLDEV'
ORA-06550: line 8, column 1:
PL/SQL: Statement ignored
06550. 00000 - "line %s, column %s:\n%s"
*Cause: Usually a PL/SQL compilation error.
*Action:
Can some one please tell me what i'm doing wrong.
Apologies if this is to much information or my formating is wrong.
You are confused between the declaration section and arguments sections of the procedure.
Your first error is due to the fact that you placed your supposedly arguments in the declaration section. then when you tried to add length to it, it compiled, but you left the procedure without arguments. then you run it with four arguments which caused the error since the procedure is created accepting no arguments.
create or replace procedure_name(
parameter1 datatype, --arguments section
parameter2 datatype
) AS
/*declaration section*/
variable1 datatype(length);
variable2 datatype(length);
BEGIN
/*your code here*/
END;
try this revise script
CREATE OR REPLACE PROCEDURE ADD_LOCATION_VIASQLDEV (Dis_Msg VARCHAR2,
ploccode VARCHAR2,
pminqty NUMBER,
pmaxqty NUMBER ) AS
BEGIN
dbms_output.put_line('--------------------------------------------------');
dbms_output.put_line('Adding location LocCode: ' || ploccode || ' MinQty: ' || pminqty || 'MaxQty' || pmaxqty);
ADD_LOCATION_TO_DB(ploccode, pminqty, pmaxqty);
dbms_output.put_line(Dis_Msg);
END;
In your first set of errors, you declared the function as using a VARCHAR2 variable, but didn't state a length in brackets after it. State a length
In your second set of errors you called the function add_location_viasqldev which takes 0 arguments, but you provided 3. Provide another argument or call a different function
Also, you can make your if/else a bit neater by doing:
IF test
ELSIF test
ELSIF test
ELSE
END IF;

I'm trying to use a variable from a cursor in the select statement of another cursor in pl/sql

I need to run a query that finds me the first 20 vehicles that are as close to another vehicle with specific terms. I'm writing this in SQL Developer on an oracle database.
Here's what I have so far:
DECLARE
TYPE cur_type IS REF CURSOR;
CURSOR lost_vehicles_cur IS
select
v.vin,
V.VEHICLE_ID
from d_vehicles V
where v.system_id =4 ;
make_cur cur_type;
l_cur_string VARCHAR2(2000);
l_make <type>;
l_model <type>;
l_vin <type>;
BEGIN
FOR vehicle IN lost_vehicles_cur LOOP
dbms_output.put_line('lost vehicle is '|| vehicle.vehicle_id);
l_cur_string := 'SELECT make_name, model_name,vin FROM vehicles where make=(select make from vehicles where vehicle_id= '
|| vehicle.vehicle_id || 'and rownum<=20 and system_id=3 and vehicle_status_id in (13,14) ';
OPEN make_cur FOR l_cur_string;
LOOP
FETCH make_cur INTO l_make, l_model, L_vin;
EXIT WHEN make_cur%NOTFOUND;
dbms_output.put_line('Related vehicles are ' || l_make || l_model || L_vin);
END LOOP;
CLOSE make_cur;
END LOOP;
END;
I used a previous answer to get to this however I get the following error when I run this:
ORA-06550: line 32, column 13: PLS-00103: Encountered the symbol "<" when expecting one of the following: constant exception table long double ref char time timestamp interval date binary national character nchar 06550. 00000 - "line %s, column %s:\n%s" *Cause: Usually a PL/SQL compilation error. –
You have to use parametrized cursor or dbms_sql:
DECLARE
TYPE cur_type IS REF CURSOR;
CURSOR lost_vehicles_cur IS
select
v.vin,
V.VEHICLE_ID
from d_vehicles V
where v.system_id =4 ;
cursor l_cur (ip_id in d_vehicles.VEHICLE_ID%type)
SELECT make_name, model_name,vin
FROM vehicles
where make in (select make
from vehicles
where vehicle_id= ip_id
and rownum<=20
and system_id=3
and vehicle_status_id in (13,14));
make_cur cur_type;
l_cur_string VARCHAR2(2000);
l_make <type>;
l_model <type>;
l_vin <type>;
BEGIN
FOR vehicle IN lost_vehicles_cur LOOP
dbms_output.put_line('lost vehicle is '|| vehicle.vehicle_id);
OPEN make_cur FOR l_cur (vehicle.vehicle_id);
LOOP
FETCH make_cur INTO l_make, l_model, L_vin;
EXIT WHEN make_cur%NOTFOUND;
dbms_output.put_line('Related vehicles are ' || l_make || l_model || L_vin);
END LOOP;
CLOSE make_cur;
END LOOP;
END;

PLSQL does not compile when substracting two long variables

I'm writing a pretty basic procedure where I need to substract two long variables and assign the value to the other variable. But the code doesn't compile and I am getting hopeless - why is that?
create or replace PROCEDURE TrendCalculator(p_id Prodeje.product%TYPE)
AS
v_week_last Prodeje.WEEK%TYPE;
v_week_current Prodeje.WEEK%TYPE;
v_year_last Prodeje.YEAR%TYPE;
v_year_current Prodeje.YEAR%TYPE;
v_weekly_sales_last PRODEJE.SALES%TYPE;
v_weekly_sales_current PRODEJE.SALES%TYPE;
v_pomocna PRODEJE.SALES%TYPE;
CURSOR c_data IS SELECT WEEK, YEAR, SALES FROM Prodeje WHERE PRODUCT = p_id ORDER BY YEAR, WEEK ASC;
BEGIN
v_pomocna := 0;
OPEN c_data;
LOOP
FETCH c_data INTO v_week_current, v_year_current, v_weekly_sales_current;
EXIT WHEN c_data%NOTFOUND;
IF (v_weekly_sales_last IS NOT NULL) THEN
DBMS_OUTPUT.PUT_LINE(p_id || ' ' || v_week_current || ' ' || v_year_current || ' ' || v_weekly_sales_current);
v_pomocna := (v_weekly_sales_current - v_weekly_sales_last);
END IF;
v_week_last := v_week_current;
v_year_last := v_year_current;
v_weekly_sales_last := v_weekly_sales_current;
END LOOP;
CLOSE c_data;
END;
The Error messages I'm getting are:
Error(19,9): PL/SQL: Statement ignored
Error(19,95): PLS-00306: wrong number or types of arguments in call to '-'
And PRODEJE.SALES Datatype is LONG.
v_weekly_sales_last is not set to anything. So line 19 evaluates to
v_pomocna := (v_weekly_sales_current - );
Which seems to be the cause of your error.

PL/SQL invalid cursor error

So I really don't have any idea why my cursor isn't working. The select statement works fine, so I'm not sure why the SQL server is throwing the error. The For loop has an implicit open and close, so that shouldn't be the problem either. Any ideas?
DECLARE
var_lname customer.c_last%TYPE;
var_fname customer.c_first%TYPE;
var_addr customer.c_address%TYPE;
var_phone customer.c_dphone%TYPE;
CURSOR expl_cursor IS SELECT c_last, c_first, c_address, c_dphone from customer;
cust_record expl_cursor%ROWTYPE;
BEGIN
DBMS_OUTPUT.PUT_LINE('ClearWater Traders Mailing List');
FOR cust_record IN expl_cursor
LOOP
FETCH expl_cursor INTO cust_record;
var_lname := cust_record.c_last;
var_fname := cust_record.c_first;
var_addr := cust_record.c_address;
var_phone := cust_record.c_dphone;
DBMS_OUTPUT.PUT_LINE(var_lname || ' ' || var_fname || ' ' ||
var_addr || ' ' || var_phone);
END LOOP;
END;
Here's the error:
ERROR at line 1:
ORA-01001: invalid cur
ORA-06512: at line 15
Ah I solved this. Can't do a FETCH inside a for loop. Since the cursor is incremented automatically.