PL SQL wrong output - oracle

I am trying to write a code which checks whether a number is binary or not.
Here is my code.
declare
n INTEGER:=#
ch number:=0;
begin
loop
exit when n=0;
if(mod(n,10)!=0 or mod(n,10)!=1) then
ch:=1;
exit;
end if;
n:=n/10;
end loop;
if ch=1 then
dbms_output.put_line('Not a Binary number.');
else
dbms_output.put_line('Binary!!!');
end if;
end;
/
I am using Oracle 11g SQL Plus.
Sometimes it is giving error at line 2. Here is the snippet of error.
old 2: n INTEGER:=#
new 2: n INTEGER:=;
n INTEGER:=;
*
ERROR at line 2:
ORA-06550: line 2, column 12:
PLS-00103: Encountered the symbol ";" when expecting one of the following:
( - + case mod new not null <an identifier>
And if it is running correctly then for every number it is giving the same output as 'Not a Binary number.'.

Change the OR by AND in the IF statement. It seems to do what you want.
DECLARE
n INTEGER := &num;
ch NUMBER := 0;
BEGIN
LOOP
EXIT WHEN n = 0;
IF MOD(n, 10) != 0
AND MOD(n, 10) != 1
THEN
ch := 1;
EXIT;
END IF;
n := n / 10;
END LOOP;
IF ch = 1
THEN
dbms_output.put_line('Not a Binary number.');
ELSE
dbms_output.put_line('Binary!!!');
END IF;
END;
/

Related

For oracle function to know if data is prime or not. Getting Warning: Function created with compilation errors

Wanted to create a function that can return records containing the number data type which are prime number
But getting warning of compilation error. What is the mistake in the code.I am a beginner in pl/sql.
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
BEGIN
DECLARE
prime_or_notPrime number;
counter number;
retVal:= 1;
prime_or_notPrime:= 1
counter:= 2
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime: = 0
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
retVal: = 1;
counter: = counter + 1
END IF;
END LOOP;
return retVal;
END;
/
What is the mistake in the code
The DECLARE is invalid syntax for a function/procedure. You want to declare the variables between the IS and BEGIN keywords.
Then you are missing a ; statement terminator after prime_or_notPrime:= 1 and counter:= 2.
Then you have:
prime_or_notPrime: = 0 instead of prime_or_notPrime := 0;
retVal: = 1; instead of retVal := 1; and
counter: = counter + 1 instead of counter := counter + 1; (they all have a space between : and = and some are missing ; again).
You never set retVal to anything other than 1.
You do not handle NULL values or values lower than 2.
Fixing that (and the indentation) gives:
CREATE OR REPLACE FUNCTION isPrime (num number)
RETURN number
IS
retVal number;
prime_or_notPrime number;
counter number;
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
retVal:= 1;
prime_or_notPrime:= 1;
counter:= 2;
WHILE (counter <= num/2) LOOP
IF (mod(num ,counter)= 0) THEN
prime_or_notPrime := 0;
retVal := 0;
EXIT;
END IF;
IF (prime_or_notPrime = 1 ) THEN
counter := counter + 1;
END IF;
END LOOP;
return retVal;
END;
/
Note: the prime_or_notprime variable is not controlling anything as, as soon as you set it to 0 you EXIT from the loop so it will never be used again. Having noted that, you can get rid of the final IF statement and just always increment the counter.
You can simplify it to:
CREATE OR REPLACE FUNCTION isPrime (
num number
) RETURN number DETERMINISTIC
IS
BEGIN
IF NUM IS NULL OR NUM < 2 THEN
RETURN 0;
END IF;
FOR counter IN 2 .. SQRT(num) LOOP
IF MOD(num, counter) = 0 THEN
RETURN 0;
END IF;
END LOOP;
RETURN 1;
END;
/
You can then consider improvements. Such as starting by checking 2 as a special case and then skipping all the other even numbers.
db<>fiddle here

Error in PL/SQL code and cannot understand the error and mistake in the code

declare
sum number:=0;
count number:=0;
pnum number:=0;
temp number;
begin
for i in 1..25
loop
temp:=i;
count:=0;
for j in 1..25
loop
if mod(i,j)=0 then
count:=count+1;
end if;
end loop;
if count=2 then
sum:=sum+temp;
pnum:=pnum+1;
end if;
exit when pnum=10;
end loop;
dbms_output.put_line(sum);
end;
Error encountered on Oracle server:
ORA-06550: line 21, column 17: PLS-00103: Encountered the symbol "+"
when expecting one of the following:
(
ORA-06512: at "SYS.WWV_DBMS_SQL_APEX_180200", line 548 ORA-06550: line
28, column 25: PLS-00103: Encountered the symbol ")" when expecting
one of the following:
(
You are using reserved words SUM and COUNT; if you edit the name of your variables your code will work:
DECLARE
vSUM NUMBER := 0;
vCOUNT NUMBER := 0;
pnum NUMBER := 0;
temp NUMBER;
BEGIN
FOR i IN 1 .. 25
LOOP
temp := i;
vCOUNT := 0;
FOR j IN 1 .. 25
LOOP
IF MOD(i, j) = 0
THEN
vCOUNT := vCOUNT + 1;
END IF;
END LOOP;
IF vCOUNT = 2
THEN
vSUM := vSUM + temp;
pnum := pnum + 1;
END IF;
EXIT WHEN pnum = 10;
END LOOP;
DBMS_OUTPUT.put_line(vSUM);
END;

PLSQL (finding range of prime number to 1000 )

DECLARE
n NUMBER;<br>i NUMBER;
pr NUMBER;
BEGIN
FOR n IN 2 .. 1000 LOOP
pr := 1;
FOR i IN 2 .. n / 2 LOOP
IF MOD(n, i) = 0 THEN
pr := 0;
END IF;
END LOOP;
IF (N = 997) THEN
DBMS_OUTPUT.PUT(n);
pr:=2;
ELSE
IF pr = 1 THEN
DBMS_OUTPUT.PUT(n||'&');
END IF;
END if;
END LOOP;
dbms_output.new_line;
END;
output should be as in one line----> 2&3&5&7&11&13&17&19&23&29&31&37&41&43&47&53&59&61&67&71&73&79&83&89&97&101&103&107&109&113&127&131&137&139&149&151&157&163&167&173&179&181&191&193&197&199&211&223&227&229&233&239&241&251&257&263&269&271&277&281&283&293&307&311&313&317&331&337&347&349&353&359&367&373&379&383&389&397&401&409&419&421&431&433&439&443&449&457&461&463&467&479&487&491&499&503&509&521&523&541&547&557&563&569&571&577&587&593&599&601&607&613&617&619&631&641&643&647&653&659&661&673&677&683&691&701&709&719&727&733&739&743&751&757&761&769&773&787&797&809&811&821&823&827&829&839&853&857&859&863&877&881&883&887&907&911&919&929&937&941&947&953&967&971&977&983&991&997
but not working in hackerrank compiler question is "Print Prime Numbers"
There's no problem in your code to produce the desired string except <br>i NUMBER;
Just comment out that piece in the declaration section as below :
DECLARE
n NUMBER; -- <br>i NUMBER;
pr NUMBER;
Here's a Demo for it.

For loop and its reverse based on if-condition/ternary operation in Oracle

In Oracle, I have the following almost identical SQL in an if-else block of a stored procedure:
if v_endsid = '15' then
FOR i IN 1..v_num LOOP --loop around the number from the beginning
v_item := TRIM(SUBSTR(v_str, (i - 1) * 12 + 1, 12)); --now this is the evaluated item
if v_item = TRIM(cursorElement.ITEM) then --this is the time to break
break;
end if;
END LOOP;
else
FOR i IN REVERSE 1..v_num LOOP --loop around the number from the last
v_item := TRIM(SUBSTR(v_str, (i - 1) * 12 + 1, 12)); --now this is the evaluated item
if v_item = TRIM(cursorElement.ITEM) then --this is the time to break
break;
end if;
END LOOP;
end if;
As you can see, the only difference between the SQL in the if and else blocks is the FOR loop. One is a forward for loop, another is a reversed (backward) for loop.
Is there any way to combine the block? I am trying this:
FOR i IN (case when v_endsid = '15' then 1..v_num else REVERSE 1..v_num end) LOOP
v_item := TRIM(SUBSTR(v_str, (i - 1) * 12 + 1, 12)); --now this is the evaluated item
if v_item = TRIM(cursorElement.ITEM) then --this is the time to break
break;
end if;
END LOOP;
But it gives me compilation error in the 1..v_num:
Found: '..' Expecting: END -or- ELSE -or- WHEN -or- OR -or- AND -or-
BETWEEN IN LIKE LIKE2 LIKE4 LIKEC MEMBER SUBMULTISET -or- ! != < <= <>
= > >= ^ ^= IS NOT ~
There is no way of dynamically changing the direction of the for loop. The only thing you can do here if you want to combine the two blocks is to use a basic loop
if v_endsid = '15' then
i := 1;
reverse := false;
else
i := v_num;
reverse := true;
end if;
LOOP --loop around the number from the beginning
v_item := TRIM(SUBSTR(v_str, (v_num - 1) * 12 + 1, 12)); --now this is the evaluated item
if v_item = TRIM(cursorElement.ITEM) then --this is the time to break
break;
end if;
if reverse = true then
if i = 1 then
exit;
else
i := i - 1;
else
if i = v_num then
exit;
else
i := i + 1;
end if;
end if;
END LOOP;
The final solution I adapt is by using basic LOOP and some ternary operations:
i := case when v_endsid = '15' then 1 else v_num end; --evaluates from front or back depending on the case
Loop
v_item := TRIM(SUBSTR(v_str, (i - 1) * 12 + 1, 12)); --now this is the evaluated item
--other queries
i := i + (case when v_endsid = '15' then 1 else -1 end);
exit when i = 0 or i = v_num + 1; --exceeds the elements
end loop;
This, I think, is a fairly neat working replacement for the original SQL
How about the another way round ? Instead of manipulating the loop condition encapsulate the code evaluating the break condition into a function that can be called from the different loops.
declare
v_reverse constant boolean := true;
-- your parameters and break rule can be arbitrary complex, mine is simple
-- as this is just a demonstration
function break(i in pls_integer) return boolean is
begin
return 13 = i;
end;
begin
if v_reverse
then
for i in reverse 1 .. 15
loop
dbms_output.put_line(i);
exit when break(i);
end loop;
else
for i in 1 .. 15
loop
dbms_output.put_line(i);
exit when break(i);
end loop;
end if;
end;
/

how to find sum of even digit in plsql?

declare
n number(4);
s number(4);
i number(4);
count number(4);
begin
n:=&n;
s:=0;
count:=0;
while (n>0 AND count MOD 2 = 0)
loop
i:= n mod 10;
s:=s+i;
n:=trunc(n / 10) ;
count:=count+1;
end loop;
dbms_output.put_line('Sum of digit = ' || s);
end;
I have tried it but getting error:
ERROR at line 12:
ORA-06550: line 12, column 23:
PLS-00204: function or pseudo-column 'COUNT' may be used inside a SQL statement
only
ORA-06550: line 12, column 8:
PL/SQL: Statement ignored
You must rename COUNT variable because it is reserved word in Oracle.
But I am not sure that your logic is right.
First step - cnt=0, mod(cnt , 2) = 0, you inside your loop
Second step - cnt=1, mod (cnt,2) = 1, you will not step inside cycle and while will be ended. Maybe you should do IF MOD(cnt,2) = 0 THEN ....
I renamed count to cnt
MOD is a function, not an operator. Try:
while (n > 0 AND MOD(count, 2) = 0)
count should be "count" bcz it's reserved word condition in while is not correct. if as in sample below n=150 result will be zero
declare
n number(4);
s number(4);
i number(4);
"count" number(4);
begin
n:=150;
s:=0;
"count":=0;
while (n>0)
loop
i:= n mod 10;
s:=s+i;
n:=trunc(n / 10) ;
if ("count" MOD 2 = 0)
then
"count":="count"+1;
end if;
end loop;
dbms_output.put_line('Sum of digit = ' || s);
end;

Resources