I want to run this code on PL/SOL to show how many activities in sporting clubs are on my database. Here is my code:
declare
Sporting_clubs_name sporting_clubs.name%type;
Count_of_activity number(2);
begin
for Sporting_clubs_name in
(select sporting_clubs.name,
count(club_activity.activity)
into Sporting_clubs_name, Count_of_activity
from sporting_clubs, club_activity
where sporting_clubs.club_id = club_activity.club_id
group by sporting_clubs.name)
loop
dbms_output.put_line('The '||Sporting_clubs_name||' has '||Count_of_activity||' activities.');
end loop;
end;
When I run it shows:
The has activities.
The has activities.
The has activities.
The has activities.
It should be shown the sporting club's name and count of activity of the output, but the "Sporting_clubs_name" and "Count_of_activity" is blank.
I also change "Sporting_clubs_name" to varchar2(20), but it still not working.
What is wrong is my code, and how can I fix it?
You cannot use select ... into in a PL/SQL for .. in (select..) loop.
Sporting_clubs_name is the name of the loop-varable and a variable whowse type corresponds to sporting_clubs.name%type.
I'd think that the code you posted doesn't even compile.
Remove your variables (Sporting_clubs_name and Count_of_activity),
give count(club_activity.activity) an alias (for example cnt) and then use
dbms_output.put_line('The '||Sporting_clubs_name.name||' has '||Sporting_clubs_name.cnt||' activities.'); instead.
just use implicit cursor loop template like here
begin
for c in (select sporting_clubs.name,
count(club_activity.activity) as cnt
from sporting_clubs, club_activity
where sporting_clubs.club_id = club_activity.club_id
group by sporting_clubs.name )
loop
dbms_output.put_line('The '||c.name||' has '||c.cnt||' activities.');
end loop;
end;
Related
Our question is showing all the countries that have names that are exactly 5 letter long. This is the cursor code and I want add if condition into it.
declare
cursor cursor_full is select * from country_cont;
begin
for counter in cursor_full
loop
dbms_output.put_line(counter.country|| ' ' || counter.continent);
end loop;
end;
However my professor said that you can't using where clause within the select statement and you should display all the countries and continent.
so i tried this code:
declare
country varchar(50);
cursor cursor_full is select * from country_cont;
begin
if length(country)=5 then
for counter in cursor_full
loop
dbms_output.put_line(counter.country|| ' ' || counter.continent);
end loop;
end if;
end;
the script output show that PL/SQL procedure successfully completed but nothing return in DBMS output
Hope someone can help me, I spent whole night to think about it,please!
Variable country doesn't contain any value, it is null so if condition is never true and loop is never executed. Sample data would help; meanwhile, see if this helps.
begin
for cur_r in (select * from country_cont) loop
if length(cur_r.country) > 5 then
dbms_output.put_line(cur_r.country|| ' ' || cur_r.continent);
end loop;
end;
Don't forget to set serveroutput on.
I have a project where i have to check if how many products are left to sell from a company for certain clients. A client can have many companies, also i have to refuse when a client or a product don't exist.
I have a table where i have clients and companies, then i got another where i have companies and products. I'm trying to create cursors to manage on the "companie-product" table, just the companies that the client can buy from, but when i declare a cursor it says "it's not a cursor" i've tryed the %rowtype, also the %type, and neither work. Does anyone know how i can fix it?
CREATE OR REPLACE PROCEDURE Transaccion
IS
my_cantidaRechazada NUMBER;
CURSOR peti
IS
SELECT idCliente, idProducto, cantidadPedido
FROM TABLAS_COMP.peticiones
ORDER BY idCliente ASC;
CURSOR empresaCliente
IS
SELECT *
FROM TABLAS_CL.empresacliente
ORDER BY tablas_cl.empresacliente.empresa;
empC empresaCliente%ROWTYPE;
CURSOR empresaProducto (vempresa NUMBER)
IS
SELECT *
FROM TABLAS_PRO.empresaproducto
WHERE empresa = vempresa
ORDER BY tablas_pro.empresaproducto.empresa ASC;
empP empresaProducto%ROWTYPE;
BEGIN
FOR cont IN peti
LOOP
IF existecliente (cont.idCliente) = 0
THEN
my_cantidaRechazada := cont.cantidadPedido;
INSERT INTO TABLAS_COMP.rechazados
VALUES (cont.idCliente,
cont.idProducto,
cont.cantidadPedido,
my_cantidaRechazada);
ELSIF existeproducto (cont.idProducto) = 0
THEN
my_cantidaRechazada := cont.cantidadPedido;
INSERT INTO TABLAS_COMP.RECHAZADOS
VALUES (cont.idCliente,
cont.idProducto,
cont.cantidadPedido,
my_cantidaRechazada);
END IF;
SELECT *
INTO empC
FROM TABLAS_CL.empresacliente
WHERE Cliente = cont.idCliente
ORDER BY empresa ASC;
FOR empP IN empC
LOOP -- (here's where the error is showed, it says "empC it's not a cursor")
SELECT *
INTO empP
FROM TABLAS_PRO.empresaproducto
WHERE Empresa = empC.Empresa;
END LOOP;
END LOOP;
END Transaccion;
Thanks in advance, David.
It would help if you specified oracle error exactly, along with the ORA-XXXXX error code. Saying it in your words can be ambiguous.
Anyway: what you indicated is wrong, really. Should be
-- wrong: for empP in empC loop
for empP in empresaProducto loop
...
end loop;
because empP is declared as empresaProducto cursor variable.
Though, SELECT you put into the loop is meaningless - you already have empP, so - why would you insert into it again? Think it over.
I have a PL/SQL file that has a loop structure.
The script is as follows.
SET SERVEROUTPUT ON
declare
c_id employee.id%type;
c_name employee.name%type;
c_address employee.address%type;
CURSOR c_employee is
SELECT id, name, address from employee;
begin
open c_employee;
LOOP
FETCH c_employee into c_id, c_name, c_address;
EXIT when c_employee%notfound;
dbms_output.put_line(c_id||' '||c_name||' '||c_address);
END LOOP;
close c_employee;
end;
/
When I run this from SQLPlus I get only the details of the first row but not the rest. What am I doing wrong? How to get all the outputs for the loop.
Try to convert your code to use a for loop instead of the open statement, like so -
for r_employee in c_employee
LOOP
dbms_output.put_line(r_employee.c_id||' '||r_employee.c_name||' '||r_employee.c_address);
END LOOP;
Where r_employee is a variable of employee%type.
The way you currently wrote it does not iterate through the cursor, and this is why only the first row is presented.
Even though your code looks correct, it should iterate through all the
row not just one. Try to use below snippet and run it in SQL plus if
still single row then there may be some other issue.
SET SERVEROUTPUT ON
DECLARE
BEGIN
FOR I IN
(SELECT id, name, address FROM employee
)
LOOP
dbms_output.put_line(I.ID||' '||I.name||' '||I.address);
END LOOP;
END;
/
Im doing a college assignment that requires me to create a PLSQL procedure that where the user can add a new customer order containing a number of items and the quantity for each item. I came up with the following that would ask the user to input a number of items to be added to the order and would then use a loop to ask for specific details such as product no and quantity. Im having problems with the user input at runtime though... When compiling the code it asks for the product code and quantity and wont ask again at runtime instead it saves the values given earlier at compile...
CREATE OR REPLACE
PROCEDURE Add_Order (Item_amount IN NUMBER, CustNo IN NUMBER) AS
ItemNo NUMBER;
var_Quantity NUMBER;
var_PONo NUMBER;
BEGIN
IF Item_amount BETWEEN 2 AND 9 THEN
SELECT seq_PONo.NEXTVAL INTO var_PONo from dual;
INSERT INTO PurchaseOrder_tab
SELECT var_PONo, REF(C),
SYSDATE,
ItemList_tab()
FROM Customer_tab C
WHERE C.CustNo = CustNo;
FOR i IN 1..Item_amount LOOP
DBMS_OUTPUT.PUT_LINE('INSIDE LOOP');
ItemNo := &Enter_ProdCode;
var_Quantity := &Quantity_Amount;
INSERT INTO TABLE (
SELECT P.ItemList
FROM PurchaseOrder_tab P
WHERE P.PONo = var_PONo
)
SELECT seq_ItemNo.nextval, REF(Pr), var_Quantity
FROM Products_tab Pr
WHERE Pr.ProductCode = ItemNo ;
DBMS_OUTPUT.PUT_LINE('Added '||var_Quantity ||' items of '||ItemNo||' to order No: '||var_PONo);
END LOOP;
ELSE
DBMS_OUTPUT.PUT_LINE('Amount of items entered onto an order must be between 2 - 9. Please try again with correct amount.');
END IF;
EXCEPTION
WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE('Operation failed '||'SQLCODE: '||SQLCODE);
DBMS_OUTPUT.PUT_LINE('SQL Error Message '||SQLERRM);
ROLLBACK;
END;
/
Short answer: you can't. PL/SQL is executed inside the database engine, and the database engine has no access to the terminal window (or database tool) you are using to start the procedure.
The code in your quesion seems to partially work, because it asks for input once, but what really happens is that: the tool (SQL*Plus, SQL Developer or whatever) parses over the PL/SQL block and sees the &-Signs, so it asks what to replace them with. Once the input is given, the PL/SQL-Block - including the entered values - is given to the database for execution.
Since you can't do that in PL/SQL, better create a front-end program first that collects the values, then sends them to the database.
Try to play around with :
BEGIN
DBMS_OUTPUT.GET_LINE(:buffer, :status);
END;
Instead of using & refferences
To Get data input from the USer,
SET SERVEROUTPUT ON;
ACCEPT Enter_ProdCode VARCHAR2 PROMPT "Please enter Product code : ";
ItemNo := &Enter_ProdCode;
I have a select statement that I am trying to loop over and increment a variable based on the condition of the select statement, then return the variable as an out so I can do something with it in some front end code. I am using oracle 11g and I am seeing a few ways I can do this... but I am not sure which is the best way. I have some of what I am trying to do below, but again stopped because of confusion.
First I am setting my proc and 'in variable'
PROCEDURE SEEKER (pMonkeyID IN Number, vMarkCounter OUT Number)
AS
BEGIN
CURSOR seeker_cur IS
Select Mokney_approved, Monkey_vaulted
from MonkeyBookApps
where MonkeyID = pMonkeyID
and Monkey_doc_type = 'BANANA'
order by docu_approv_timestamp,monkey_doc_type,monkey_doc_approved desc
OPEN seeker_cur;
begin
OPEN Seeker_cur;
vMarkCounter := 0;
Here is the part I am not sure about. Should I loop and then exit if the condition is not met or should I do an if statement and somehow determine if there is a record that could be greater than one? If so how would that work? Is there a benefit to doing one way over the other? So... I am going to sudo-code what I am trying to do (below):
FOR (however many records) in Seeker_cur
IF seeker_cur (not found) or (returns no records)
EXIT or (break for loop);
ELSE
LOOP
vMarkCounter := vMarkCounter + 1;
EXIT WHEN seeker_cur is out of records (somehow)
END IF;
END LOOP;
END;
END SEEKER;
I am sure there are a few ways to do this. What ways would you suggest?
why dont you use implicit cursor , it will open and close itself:
DECLARE
CURSOR seeker_cur IS
Select Mokney_approved, Monkey_vaulted
from MonkeyBookApps
where MonkeyID = pMonkeyID
and Monkey_doc_type = 'BANANA'
order by docu_approv_timestamp,monkey_doc_type,monkey_doc_approved desc;
vMarkCounter number:=0;
BEGIN
FOR i IN seeker_cur
LOOP
vMarkCounter := vMarkCounter+1;
END LOOP;
dbms_output.put_line(vMarkCounter);
END;
It seems to me that the solution your problem might be as simple as this:
SELECT COUNT(*)
INTO l_some_local_variable
FROM monkey_book_apps
WHERE monkey_id = p_monkey_id
AND monkey_doc_type = 'BANANA';
RETURN l_some_local_variable;
Avoiding PL/SQL loops and using the simplest SQL possible is (almost always) the most efficient way. Tom Kyte calls the row-by-row execution of LOOPs "slow-by-slow".