Function returning error texts in Oracle APEX - sql

I am trying to take a count of the records in the interactive grid and based on that I am trying to pass a message to the user. However, I am getting error : ORA-06550: line 1, column 141: PLS-00103: Encountered the symbol "NUMBER" when expecting one of the following: := . ( # % ; The symbol "." was substituted for "NUMBER" to continue.Following is my code in the validation. Validation Type is : Function Returning Error Text.
l_count NUMBER := 0;
BEGIN
SELECT COUNT(1)
INTO l_count
FROM ugh
WHERE ugh.pre = :PRE
AND ugh.APP1 = :APP1
AND ugh.APP2 = :APP2
AND ugh.APP3 = :APP3
AND ugh.FINL_APP = :FINL_APP;
IF l_count > 1 THEN
IF END_DATE IS NULL THEN
RETURN 'Error Message to be displayed.';
ELSE
RETURN NULL;
END IF;
ELSE
RETURN NULL;
END IF;
END;
Can anyone please help ?

Looks like you're missing the DECLARE keyword:
DECLARE --> this
l_count NUMBER := 0;
BEGIN
SELECT COUNT (1)
INTO l_count
FROM ugh
Also, what is END_DATE? You never declared it. If it is a page item, then precede it with a colon, :END_DATE

Related

PL/SQL Function to check whether a number is prime or not

Please find the error and rectify this code
This is a PL/SQL function to check whether a number is prime or not
By using the flag method instead of using count to check the requirement, it's working perfectly but not for this method.
create or replace function isprime(x in number)
RETURN number
IS
i int;
count int;
BEGIN
count:=0;
for i in 2..x/2 LOOP
if mod(x,i)=0 then
count:=count+1;
end if;
end loop;
return count;
end;
/
Warning: Function created with compilation errors.
DECLARE
n int;
c int;
BEGIN
n:=&n;
c:=isprime(n);
if c=0 then
dbms_output.put_line(n||'is a prime number');
else
dbms_output.put_line(n||'is not prime');
end if;
end;
/
Enter value for n: 5
old 5: n:=&n;
new 5: n:=5;
c:=isprime(n);
*
ERROR at line 6:
ORA-06550: line 6, column 4:
PLS-00905: object SYSTEM.ISPRIME is invalid
ORA-06550: line 6, column 1:
PL/SQL: Statement ignored
Here is the error list:
SQL> show errors
Errors for FUNCTION ISPRIME:
LINE/COL ERROR
-------- -----------------------------------------------------------------
10/1 PL/SQL: Statement ignored
10/8 PLS-00204: function or pseudo-column 'COUNT' may be used inside a
SQL statement only
13/1 PL/SQL: Statement ignored
13/8 PLS-00204: function or pseudo-column 'COUNT' may be used inside a
SQL statement only
COUNT is reserve sql word, have a look at this as an alternative solution for this task.
DECLARE
value_ NUMBER default :A;
i NUMBER DEFAULT 5;
is_prime VARCHAR2(5 CHAR);
BEGIN
IF value_ = 2 OR value_ = 3 THEN
is_prime := 'TRUE';
ELSIF MOD(value_,2)=0 OR MOD(value_,3)=0 OR value_ <= 1 THEN
is_prime := 'FALSE';
END IF;
WHILE POWER(i,2) <= value_ LOOP
IF MOD(value_,i)=0 OR MOD(value_,i + 2)=0 THEN
is_prime := 'FALSE';
exit;
END IF;
i := i + 6;
end loop;
is_prime := nvl(is_prime,'TRUE');
DBMS_Output.Put_Line(is_prime||' IT IS '||CASE is_prime WHEN 'FALSE' THEN 'NOT' END||'A PRIME NUMBER');
END;

PLS-00103: Encountered the symbol "=" when expecting one of the following.... in PL/SQL script

create or replace function lstnation (listdisplay in varchar2)
return varchar2 is
nName varchar2 (1000) default null;
listD varchar2(1000) default null;
cursor display_nation
is
select nation.n_name
from nation
inner join region
on region.r_regionkey = nation.n_nationkey
where region.r_regionname = listdisplay;
BEGIN
open display_nation;
loop
fetch display_nation into nName;
exit when display_nation%notfound;
IF
listD := listD || RTRIM(nName)||' , ';
end loop;
close display_nation;
return listD;
end lstnation;
/
DECLARE
rKey region.r_regionkey%type;
rName region.r_name%type;
nList varchar2(1000);
cursor outer_block is
select region.r_regionkey, region.r_name, lstnation(region.r_name)
from region;
BEGIN
open outer_block;
loop
fetch outer_block into rKey, rName, nList;
exit when outer_block%notfound;
dbms.output.put_line(rkey || ' ' || RTRIM(rName) || ': '|| nList);
end loop;
close outer_block;
end;
/
I get two errors, how can I fix it
LINE/COL ERROR
19/12 PLS-00103: Encountered the symbol "=" when expecting one of the
following:
. ( * # % & = - + < / > at in is mod remainder not rem then
<an exponent (**)> <> or != or ~= >= <= <> and or like like2
like4 likec between || multiset member submultiset
20/2 PLS-00103: Encountered the symbol "END" when expecting one of the
following:
begin function pragma procedure subtype type
current cursor delete
exists prior
You can save some coding and efficiency by replacing the cursor loop with the listagg function
select listagg(rtrim(nation.n_name),',')
from nation
inner join region
on region.r_regionkey = nation.n_nationkey
where region.r_regionname = listdisplay;
So that will collate all the matching rows, and use whatever delimiter is passed in. One thing to be aware of, you have listD varchar2(1000) so as long as the results from the query are less than 1000, you are OK. If you expect a larger result set, you may need to increase or use a clob.
If for some reason, you still want to use the loop method, then you need to fix your IF statement:
loop
fetch display_nation into nName;
exit when display_nation%notfound;
IF <condition> THEN
listD := listD || RTRIM(nName)||' , ';
END IF;
end loop;

numeric or value error: character to number conversion error pl/sql

so I'm really just trying to output the lines to the 12 days of Christmas, just to get a handle on loops in PL/SQL, and I can't even seem to get a simple array declared correctly. Here is the code:
CREATE OR REPLACE
TYPE all_gifts is object (first_words varchar2(20), second_words varchar2(50));
/
DECLARE
type gifts is table of all_gifts;
type daysarray IS VARRAY(12) OF VARCHAR2(20);
lv_gifts GIFTS := gifts( all_gifts('and a','Partridge in a pear tree')
, all_gifts('Two','Turtle Doves')
, all_gifts('Three','French Hens')
, all_gifts('Four','Calling Birds')
, all_gifts('Five','Golden Rings')
, all_gifts('Six','Geese a laying')
, all_gifts('Seven','Swans a Swimming')
, all_gifts('Eight','Maids a milking')
, all_gifts('Nine','Ladies Dancing')
, all_gifts('Ten','Lords a leaping')
, all_gifts('Eleven','Pipers piping')
, all_gifts('Twelve','Drummers drumming')
);
second_array_elem varchar2(50);
lv_counter NUMBER := 1;
lv_days daysarray;
lv_first_word VARCHAR2(50);
BEGIN
lv_days := daysarray('First','Second','Third','Fourth','Fifth','Sixth','Seventh','Eigth','Ninth','Tenth','Eleventh','Twelefth');
FOR day in 1 .. lv_days.count loop
IF day != 'first' THEN
lv_first_word := second_array_elem;
ELSE
lv_first_word := 'A';
second_array_elem := lv_gifts.first;
END IF;
dbms_output.put_line('On the ['||lv_days(day)||'] day of Christmas');
second_array_elem := lv_gifts.next(second_array_elem);
END LOOP;
END;
/
And the console is throwing an error on the line right after my BEGIN statement (where I'm trying to declare the lv_days array) saying:
numeric or value error: character to number conversion error
But above, in my declare statement, I have it as a varying array of 12 indexes with the type of varchar2(20).
What simple step did I miss here?
Issue is with the below line of code..
IF day != 'first' THEN
As per the code, system is trying to compare the loop variable with string 'first'
You may use the below code
IF lv_days(day) != 'first' THEN

Invalid Identifier When Trying to Use Package Function in Summation Expression

I'm trying to use the sum function with a package function but running into an "invalid identifier" bug. Here's some example code with the error causing function commented
create or replace type numType as object
(
myNum number
)
;
/
create or replace type numTypes is table of numType;
/
create or replace package testNumberPackage as
function ReturnNum(in_numType numType) return number;
end;
/
create or replace package body testNumberPackage as
function ReturnNum(in_numType numType) return number is
begin
return in_numType.myNum;
end;
end;
/
declare l_numTypes numTypes;
l_count number;
begin
l_numTypes := numTypes();
for i in 1 .. 100 loop
l_numTypes.extend(1);
l_numTypes(l_numTypes.last) := numType(i);
end loop;
select sum(n.myNum) into l_count from table(l_numTypes) n;
select sum(testNumberPackage.ReturnNum(n)) into l_count from table(l_numTypes) n; --causes the error
dbms_output.put_line(l_count);
end;
/
The exact error for this code is
ORA-06550: line 11, column 42
PL/SQL: ORA-00904: "N": invalid identifier
ORA-6550: line 11, column 3:
PL/SQL: SQL Statement ignored
Thanks for any help.
The first issue is that you can't pass a table into a parameter by using its alias. It doesn't even make sense to try doing that.
The next issue is how to get the column mynum that is returned from the table(l_numTypes) into the correct format to pass into testNumberPackage.ReturnNum, since it's of NUMBER datatype, and the function is expecting a numtype parameter.
To do that, you need to pass in an object with that column, like so: numtype(n.mynum).
The following works for me:
declare
l_numTypes numTypes;
l_count number;
begin
l_numTypes := numTypes();
for i in 1 .. 100 loop
l_numTypes.extend(1);
l_numTypes(l_numTypes.last) := numType(i);
end loop;
select sum(n.myNum) into l_count from table(l_numTypes) n;
select sum(testNumberPackage.ReturnNum(numtype(n.mynum))) into l_count from table(l_numTypes) n; --causes the error
dbms_output.put_line(l_count);
end;
/
5050
Clear as mud?

pl-sql how to perfom a simple max(Date) function

hello
i am new to oracle db , how can i simply ask for the max date?
FUNCTION get_max_date_rec(
i_value_date IN vat.value_date%TYPE := app_utilities_q.server_sys_date )
RETURN vat.rec_id%TYPE
IS
v_date vat.value_date%TYPE;
BEGIN
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date
RETURN get_rec_by_date(v_date).rec_id;--compiler err
END get_max_date_rec;
EDIT
this is the err created by the compiler
Error(76,7): PL/SQL: SQL Statement ignored
Error(81,7): PL/SQL: ORA-00933: SQL command not properly ended
I want to return rec_id as writen above...
FUNCTION get_max_date_rec(
i_value_date IN vat.value_date%TYPE
default app_utilities_q.server_sys_date -- assuming this is a default
)
RETURN vat.rec_id%TYPE
IS
v_date vat.value_date%TYPE;
BEGIN
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date
RETURN v_date;
END get_max_date_rec;
One risk is that if no records in vat exist for a date greater than i_value_date, the code will fail, throwing the NO_DATA_FOUND exception. You should consider how you might wish to handle that condition - or not handle it, if that's the correct thing to do.
the problem was
not adding
;
in the end of select
SELECT MAX(v.value_date)--compiler err
INTO v_date
FROM vat v
WHERE v.value_date < i_value_date ;