IF THEN STATEMENT ORACLE APEX PS/SQL - sql

I am trying to calculate taxes, however, I keep getting an error ORA-06550. Can you please aid me?
How it should to work is
if gross pay is more than 225000 then we divide the gross pay by 3.
if gross pay is less than 225000 then set the value at 75000
This is what I tried so far:
IF nvl(:P37_GROSS_PAY,0) > (225000*nvl:(P37_PERIOD,0)) THEN
{nvl(:P37_GROSS_PAY,0)/3}
ELSE
{75000*nvl(:P37_PERIOD,0)}
END IF;

You have to put the result into something, such as a locally declared variable (and remove curly brackets; they are invalid in this context):
declare
tax number;
begin
if nvl(:P37_GROSS_PAY, 0) > 22500 * nvl(:P37_PERIOD, 0)) then
tax := nvl(:P37_GROSS_PAY, 0) / 3;
else
tax := 75000 * nvl(:P37_PERIOD, 0);
end if;
end;

Related

What do I keep getting Error: Identifier not found "parish" source.pas(7,9) Fatal: Syntax error, ";" expected but ":" found?

BEGIN
(*Declaration of variables*)
Every time I run my program I keep getting that same error that something is wrong with the syntax within this section
parish : String; (*Error: identifier not found "parish"*)
pat_mny, sa_mny, sm_mny, se_mny, sj_mny, p_mny, st_mny : Real; (*Fatal: Syntax error, ";" expected but ":" found*)
j, sa, sm, se, sj, p, st, max : Integer;
This program computes the total number of patients that visited each parish and displays the maximum parish cost
Print ('*****Ministry of Health Database File*****');
Print ('Hello, this is the Dengue Eradication Task Force Computing Program, please make sure to follow the instructions given else there will be a compile error ');
Print('ALL parishes entered MUST BE spelt correctly. Any parish from the parish list may be entered (EXCEPTIONS WILL PRODUCE A COMPILE ERROR).')
Print ('PARISH LIST: St. Ann, St. Mary, St. Thomas, St. Elizabeth, St. James and Portland');
(*Loop to ensure that the program repeats this block of code 10 times*)
(*Prompting the user for input*)
for j :=1-10 do
begin
Write ('Enter the name of the parish the patient visited: ');
Readln (parish);
Write ('Enter the amount that the patient paid:');
Readln (pat_mny);
(*Processing to compute the number of patients and the total cost for each parish*)
while (parish := "St. Ann") do
begin
sa := 1+0;
sa_mny := sa_mny+ pat_mny;
end;
while (parish := "St. Mary") do
begin
sm:=1+0;
sm_mny := sm_mny+pat_mny;
end;
while (parish := "St. Elizabeth") do
begin
se :=1+0;
se_mny := se_mny+pat_mny;
end;
while (parish := "St. Thomas") do
begin
st := 1+0;
st_mny := st_mny+pat_mny;
end;
while (parish := "St. James") do
begin
sj :=1+0;
sj_mny := sj_mny+pat_mny;
end;
while (parish := "Portland") do
begin
p:=1+0;
p_mny :=p_mny+pat_mny;
end;
end;
(*Processing to compute the maximum cost*)
max :=0;
if ( sa<sm) then
begin
max:=sm;
end;
else if (sm<se) then
begin
max:=se;
end;
else if (se<st) then
begin
max:=st;
end;
else if (st<sj) then
begin
max:=sj:
end;
else
begin
max:=p;
end;
end;
(*Prompting the computer output*)
Writeln ('St. Ann: Total cost $', sa_mny 'No. of Patients', sa)
Writeln ('St. Mary: Total cost $', sm_mny 'No. of Patients', sm)
Writeln ('St. Elizabeth: Total cost $', se_mny 'No. of Patients', se)
Writeln ('St. Thomas: Total cost $', st_mny `enter code here`'No. of Patients', st)
Writeln ('St. James: Total cost $', sj_mny 'No. of Patients', sj)
Writeln ('Portland: Total cost $', p_mny 'No. of Patients', p)
Writeln ('The maximum total cost is $', max)
Print ('Thank you for using the DETF Computing Program. Good day!')
END.
This is the correction to the code above...
Thanks to all the persons who took time out to comment on my question to help me. Thanks for your attention.
In the section where I have Var at first I had Begin and then I declared the variables without using the keyword var. I modified the code to correct the syntax error by removing the declaration of variables outside of the code block within the begin and end section. Also changed max to real datatype because I wanted it to store a floating point number.
Program DETFComputingProgram;
Var
(*Declaration of variables*)
parish : String;
pat_mny, sa_mny, sm_mny, se_mny, sj_mny, p_mny, st_mny, max: Real;
j, sa, sm, se, sj, p, st : Integer;
Earlier I did not initialize my variables. I initialize my variables within the main begin and endsection.
Begin
sa_mny:=0; sm_mny:=0; se_mny:=0; sj_mny:=0; p_mny:=0; st_mny:=0 ;
sa:=0; sm:=0; se:=0; sj:=0; p:=0; st:=0 ;
In this section of code below where I haveWriteln I had Print that caused an error also.
Writeln('*****Ministry of Health Database File*****');
Writeln ('Hello, this is the Dengue Eradication Task Force Computing Program, please make sure to follow the instructions given else there will be a compile error ');
Writeln('ALL parishes entered MUST BE spelt correctly. Any parish from the parish list may be entered (EXCEPTIONS WILL PRODUCE A COMPILE ERROR).');
Writeln('PARISH LIST: St. Ann, St. Mary, St. Thomas, St. Elizabeth, St. James and Portland');
(*Loop to ensure that the program repeats this block of code 10 times*)
(*Prompting the user for input*)
Earlier I had for j:=1-10 dothat also gives a syntax error the correct syntax is for j :=1 to 10 do. Also I added a semi-colon at the end of one of these lines in the section of code below where it was missing.
for j:=1 to 10 do
begin
Writeln('Enter the name of the parish the patient visited: ');
Readln (parish);
Writeln('Enter the amount that the patient paid:');
Readln (pat_mny);
In this section of code below I had used while loop instead of anif()thenconstruct. I had while (parish := "St.Ann") do. I learnt here that that was an illegal code (thanks) and I took the sugestion to use an if()then construct so the code looked like this if(parish = 'St.Ann') then.
(*Processing to compute the number of patients and the total cost for each parish*)
if (parish ='St. Ann') then
begin
sa := sa+1;
sa_mny := sa_mny+ pat_mny;
end;
if (parish ='St. Mary') then
begin
sm:=sm+1;
sm_mny := sm_mny+pat_mny;
end;
if (parish ='St. Elizabeth')then
begin
se :=se+1;
se_mny := se_mny+pat_mny;
end;
if (parish = 'St. Thomas') then
begin
st := st+1;
st_mny := st_mny+pat_mny;
end;
if (parish = 'St. James')then
begin
sj :=sj+1;
sj_mny := sj_mny+pat_mny;
end;
if (parish = 'Portland') then
begin
p:=p+1;
p_mny :=p_mny+pat_mny;
end;
end;
In this section of code below I had put semicolons at the end of each condition statement examplemax:=sm_mny;. Semi-colons are only supposed to go at the end of statements that come after an else in an if()then construct. Also I had made some logic errors so I fixed that in order get the correct calculations.
(*Processing to compute the maximum cost*)
max :=0;
if ( sa_mny<sm_mny) then
max:=sm_mny
else
if (sm_mny<se_mny) then
max:=se_mny
else
if (se_mny<st_mny) then
max:=st_mny
else
if (st_mny<sj_mny) then
max:=sj_mny
else
max:=p_mny;
end.
(Prompting the computer output)
Writeln ('St. Ann: Total cost $', sa_mny 'No. of Patients', sa)
Writeln ('St. Mary: Total cost $', sm_mny 'No. of Patients', sm)
Writeln ('St. Elizabeth: Total cost $', se_mny 'No. of Patients', se)
Writeln ('St. Thomas: Total cost $', st_mny 'No. of Patients', st)
Writeln ('St. James: Total cost $', sj_mny 'No. of Patients', sj)
Writeln ('Portland: Total cost $', p_mny 'No. of Patients', p)
Writeln ('The maximum total cost is $', max)
Writeln('Thank you for using the DETF Computing Program. Good day!')
End.

Having trouble creating trigger that updates column based on variable

I'm trying to create a trigger for a class that updates customer balance depending on how many days late or early the item was returned. I have a charter table that has a due date and return date, the trigger is designed to only fire when the return date is being updated. The trigger then takes the difference between return date and due date and stores that value into a variable. I have a series of if else statements that determine whether the item was returned late or early and then multiply the number of days by the late fee or early bonus. Then it updates the customer balance in the customer table to whatever the value of the fee variable is. Oracle is saying I have a syntax error on my end statement and I'm not sure what is wrong.
CREATE OR REPLACE TRIGGER Fee_Trigger
AFTER UPDATE ON CHARTER
FOR EACH ROW
WHEN ((:NEW.Return_Date <> :OLD.Return_Date AND :NEW.Return_Date IS NOT
NULL))
DECLARE
Fee NUMBER;
BEGIN
Fee := (:NEW.Return_Date - Due_Date);
IF Fee > 0 THEN Fee := (Fee * 75) ;
ELSE IF Fee < 0 THEN Fee := (Fee * 25);
ELSE IF Fee = 0 THEN FEE := Fee;
END IF;
UPDATE CUSTOMER
SET Customer_Balance = Fee
WHERE CustomerID = :NEW.CustomerID
END;
There are some little formatting errors. The following may be used, alternatively :
CREATE OR REPLACE TRIGGER Fee_Trigger
AFTER UPDATE ON CHARTER
FOR EACH ROW
WHEN ((NEW.Return_Date <> OLD.Return_Date AND NEW.Return_Date IS NOT NULL))
DECLARE
Fee NUMBER;
BEGIN
Fee := :NEW.Return_Date - :NEW.Due_Date;
IF Fee > 0 THEN Fee := (Fee * 75);
ELSIF Fee < 0 THEN Fee := (Fee * 25);
ELSIF Fee = 0 THEN Fee := Fee;
END IF;
UPDATE CUSTOMER
SET Customer_Balance = Fee
WHERE CustomerID = :NEW.CustomerID;
END;
The following issues encountered :
Due_date was not defined (:OLD.Due_Date or :NEW.Due_Date may be used)
ELSIF should be used instead of ELSE IF
UPDATE statement should be ended with a semicolon.
Remove colons before OLD and NEW inside WHEN statement.
I suggest replacing the IF/ELSIF statements with a CASE expression in the UPDATE statement:
CREATE OR REPLACE TRIGGER Fee_Trigger
AFTER UPDATE ON CHARTER
FOR EACH ROW
WHEN ((:NEW.Return_Date <> :OLD.Return_Date AND :NEW.Return_Date IS NOT NULL))
DECLARE
Due_Date DATE := TRUNC(SYSDATE); -- initialization as an example value.
nDays_between_return_and_due NUMBER;
BEGIN
nDays_between_return_and_due := TRUNC(:NEW.Return_Date - Due_Date);
UPDATE CUSTOMER
SET Customer_Balance = CASE
WHEN nDays_between_return_and_due > 0 THEN -- Returned late
nDays_between_return_and_due * 75
WHEN nDays_between_return_and_due < 0 THEN -- Returned early
nDays_between_return_and_due * 25
ELSE -- Returned on time
0
END
WHERE CustomerID = :NEW.CustomerID;
END FEE_TRIGGER;
Best of luck.

Producing a report with a stored SQL function

I am trying to produce a report that calculates a discount applied to an order using a stored function in Oracle 12c. I have a table, orders with column o_id. Each line of the order is a separate order_line table, having o_id, ol_quantity, and ol_price. If the order is over $100, a discount of $10 is applied to the order.
I have created a stored function, which compiles, but when I try to run the function I get the error:
Error(10,1): PLS-00103: Encountered the symbol "FINAL_COST" when expecting one of the following: * & - + / at mod remainder rem then <an exponent (**)> and or || multiset
Here is the function:
create or replace function DiscountsReport
(order_id IN REAL) RETURN REAL
is
percent real;
final_cost real;
being
select SUM(order_line.ol_quantity * order_line.ol_price) as total from order_line
where o_id = order_id;
if total >= 100 final_cost = 90;
return final_cost;
end;
And my code to run it is:
var cost number;
execute :cost := discountsreport(1);
print cost;
Your "if" statement is absolutely incorrect. Take a look at the documentation:
if-then-else

Procedure never raise NO_DATA_FOUND Exception

i've created an procedure which increases salaries of peoples working in a department by a certain rate. the department number and the rate are assed as parameters for the procedure.
Now, the procedure works great when i specify the good departement number, but once i specify a false one, and i'm waiting for the NO_DATA_FOUND Exception to raise, it never happen. I searched tried many thing but didn't found the answer, so if you can help me i woul be really greatfull. Thank you !
Here is my code :
create or replace PROCEDURE AugmenteSalaire(numDepartement in departements.numerodepartement%TYPE, taux IN number) IS
p_nbreTotalSalaire employes.salaireemploye%type;
begin
SELECT sum(salaireemploye)
INTO p_nbreTotalSalaire
FROM employes
WHERE numerodepartement = numDepartement;
if taux > 0 AND taux <= 100 THEN
if p_nbreTotalSalaire < 150000 THEN
Update employes e
SET e.salaireemploye = e.salaireemploye + (e.salaireemploye * (taux * 0.01))
WHERE e.numerodepartement = numDepartement
AND NOT numeroemploye = (SELECT departements.chefdepartement from departements
WHERE departements.numerodepartement = numDepartement);
ELSE
DBMS_OUTPUT.PUT_LINE('Transaction refused : The salary sum cannot be above 150000');
END IF;
ELSE
DBMS_OUTPUT.PUT_LINE('The rate cannot be under 0 or aboce 100');
END IF;
Exception
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('The department number provided is invalid, '||
'please enter a valid department number(DEP001 for example)');
end;
SELECT sum(salaireemploye)
INTO p_nbreTotalSalaire
FROM employes
WHERE numerodepartement = numDepartement;
In this query you are using SUM(). Now if there is no matching department, i.e. input "numDepartement" is a false department, sum(salaireemploye) is 0 (no such department, so nothing to add, so 0).
sum(salaireemploye) thus has a valid value, which is 0 here. Hence this will never raise a NO_DATA_FOUND exception

PL/SQL Storing and calling procedure

I am currently working on a PL/SQL problem where I have to create a cursor inside a procedure that will give the appropriate discount for a given item (10% for prices >= $100 and 5% for prices >= $10). When I have to call the procedure, I need to display the Order Number, customer First Name, Last Name, and the Total Net Cost of the items after the discount for a specific order number (in this case I need to display for order number 2). I can't get it to display this information.
Here is my code for creating the procedure with a cursor so far.
CREATE OR REPLACE PROCEDURE ComputeOrderTotal
(no_id IN orders.o_id%TYPE,
cfirst IN customer.c_first%TYPE,
clast IN customer.c_last%TYPE,
TotalNetCost OUT orders.ordertotal%TYPE) IS
CURSOR OrderCursor IS
SELECT order_line.inv_id, inv_price, ol_quantity, inv_price*ol_quantity AS ExtPrice,
CASE
WHEN inv_price*ol_quantity >= 100 THEN 0.9*(inv_price*ol_quantity)
WHEN inv_price*ol_quantity >= 10 THEN 0.95*(inv_price*ol_quantity)
ELSE
inv_price*ol_quantity
END AS NetCost
FROM inventory, order_line, orders, customer
WHERE orders.o_id = customer.c_id;
OrderRow OrderCursor%ROWTYPE;
BEGIN
OPEN OrderCursor;
LOOP
FETCH OrderCursor INTO OrderRow;
EXIT WHEN OrderCursor%NOTFOUND;
TotalNetCost :=TotalNetCost + OrderRow.NetCost;
END LOOP;
DBMS_OUTPUT.PUT_LINE('Order Number: ' || no_id || 'First Name: ' || cfirst || 'Last Name: ' ||
clast || 'Total Net Cost: ' || TO_CHAR(TotalNetCost, '$0999.99'));
END;
And here is my code for calling the procedure.
DECLARE
no_id orders.o_id%TYPE;
cfirst customer.c_first%TYPE;
clast customer.c_last%TYPE;
TotalNetCost orders.ordertotal%TYPE;
BEGIN
ComputeOrderTotal(2, cfirst, clast, TotalNetCost);
END;
Thanks for the help!
i am not sure but your conditions could be the problem as your second condition contradicts the first. for example 110 satisfy the first condition but it also satisfy the second condition.
WHEN inv_price*ol_quantity >= 100 THEN 0.9*(inv_price*ol_quantity)
WHEN inv_price*ol_quantity >= 10 THEN 0.95*(inv_price*ol_quantity)
i would suggest changing second condition to <100 and >=10
Add this line to the top of the code calling the procedure.
Alter session set serveroutput on;