PLSQL Printing prime numbers - sql

I want to print prime numbers between 1 to 50. But I don't understand what I am doing wrong in my code. After BEGIN, SQLDeveloper says I had an error because it expected another sign and not = .
SET SERVEROUTPUT ON
DECLARE
i NUMBER;
counter NUMBER;
n NUMBER;
k NUMBER;
BEGIN
i := 2;
counter := 0;
n := 50;
k := n/2;
FOR i IN 1..k LOOP
IF (n%i := 0 ) THEN
counter := 1;
END IF;
IF (counter := 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;

SET SERVEROUTPUT ON
DECLARE
i NUMBER;
counter NUMBER;
n NUMBER;
k NUMBER;
BEGIN
i := 2;
counter := 0;
n := 50;
k := floor(n/2);
FOR i IN 1..k LOOP
IF (mod(n, i) = 0 ) THEN
counter := 1;
END IF;
IF (counter = 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;
k := n/2; -- added FLOOR (k is NUMBER, by default it's NUMBER(38, max_scale))
IF (n%i := 0 ) THEN -> IF (mod(n, i) = 0 ) THEN
Oracle has MOD function for remainder + to compare you need to use =,
:= is for assignment.
DECLARE
counter NUMBER;
k NUMBER;
BEGIN
FOR n IN 1..50 LOOP
counter := 0;
k := floor(n/2);
FOR i IN 2..k LOOP
IF (mod(n, i) = 0 ) THEN
counter := 1;
END IF;
END LOOP;
IF (counter = 0) THEN
DBMS_OUTPUT.PUT_LINE(n||' is prime number');
END IF;
END LOOP;
END;

In your IF clause you are assigning the value instead of comparison. You are using := operator, where you shd be using =
It shud be like (IF counter = 0) then
......
Also I dont think n%i would work, you could do IF (trunc(n) = n) then ... or IF (mod (n,i) =0) then ...

--this function is check prime number.
create or replace function prime_a(x number) return
varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0
then ans:='not a prime';
exit;
else ans:='prime';
end if;
end loop;
return ans;
end;
/

step-1:
create table tob(prime number);
step-2:
create or replace procedure ro(m number,n number)
is
a integer;
co Boolean;
begin
for j in m..n loop
co:=false;
co:=(j=1 );
a:=(j/2);
for i in 2..a loop
co:=(mod(j,i)=0);
exit when co;
end loop;
if(not co) then
insert into tob values(J);
end if;
end loop;
commit;
end;
/
step-3:
exec ro(1,50);
step-4: check:-
select * from tob;

You should create or replace in your source code:
function prime_a(x number) return
varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0
then ans:='not a prime';
exit;
else ans:='prime';
end if;
end loop;
return ans;
end;
/

Why don't you just check for previous prime divisibility?
create table prime (primeno bigint)
declare #counter bigint
set #counter = 2
while #counter < 1000000
begin
if not exists(select top 1 primeno from prime where #counter % primeno = 0)
insert into prime select #counter
set #counter = #counter + 1
end
select * from prime order by 1
You could certainly cap the numbers you are checking against in the where condition to reduce your overheads further.

declare
i number;
j number;
k number:=0;
begin
for i in 1..50
loop
for j in 2..i-1
loop
if mod(i,j)=0 then
k:=1;
exit;
end if;
end loop;
if k=0 then
dbms_output.put_line(i);
end if;
k:=0;
end loop;
end;
/

create or replace function prime_a(x number) return varchar2 is
n integer;
ans varchar2(50);
begin
n:=(x/2);
for i in 2..n loop
if mod(x,i)=0 then
ans:='not a prime';
exit;
else
ans:='prime';
end if;
end loop;
return ans;
end;
/

Related

PL-SQL: returning error - inserting elements into (user input) index with shifting all the elements to element[i+1]

TYPE arr is VARRAY(10) of VARCHAR(32);
ar arr := arr('1', '1', '1');
idx INTEGER(100);
tmp INTEGER(100);
val VARCHAR(32);
PROCEDURE APPENDARR (arr IN OUT arr, idx IN, val IN) IS
BEGIN
if(idx > arr.LIMIT) then
tmp := (idx - arr.LIMIT);
arr.extend(tmp);
FOR i in REVERSE idx..arr.LAST LOOP
arr(i) := arr(i - 1);
if(arr(i) = arr(idx)) THEN
arr(i) := val;
END IF;
END LOOP;
ELSE
arr.extend();
arr(idx) := val;
END IF;
END;
error code:
ORA-06550: line 10, column 48:
PLS-00103: Encountered the symbol "," when expecting one of the following:
out
long double ref char time timestamp interval date binary
national character nchar
anyone who can help me with my error? sorry english is not my native language but i try my best :)!
I'm guessing this is part of a package, as otherwise you would need the create or replace syntax. For demo purposes, I put it in an anonymous block just to test compilation.
Two issues:
integer doesn't take a precision, it's just integer.
The idx and val parameters are missing datatypes.
The following compiles (I haven't checked what it does or whether there is any better implementation):
declare
type arr is varray(10) of varchar(32);
ar arr := arr('1', '1', '1');
idx integer;
tmp integer;
val varchar(32);
procedure appendarr
( arr in out arr
, idx in integer
, val in varchar2 )
is
begin
if idx > arr.limit then
tmp := idx - arr.limit;
arr.extend(tmp);
for i in reverse idx .. arr.last loop
arr(i) := arr(i - 1);
if arr(i) = arr(idx) then
arr(i) := val;
end if;
end loop;
else
arr.extend();
arr(idx) := val;
end if;
end;
begin
null;
end;
PL/SQL if conditions are terminated by the then keyword so they don't need brackets as in other languages, so I removed them.
Also, you have variables idx, tmp and val declared at the top which are not used anywhere, and which also have the same names as local variables within the procedure, which could be confusing. If there isn't some more code you haven't shown that uses them, maybe you can get rid of them.
Edit: As requested, here is what it would look like as a standalone procedure:
create or replace type arr as varray(10) of varchar(32)
/
create or replace procedure appendarr
( arr in out arr
, idx in integer
, val in varchar2 )
as
tmp integer;
begin
if idx > arr.limit then
tmp := idx - arr.limit;
arr.extend(tmp);
for i in reverse idx .. arr.last loop
arr(i) := arr(i - 1);
if arr(i) = arr(idx) then
arr(i) := val;
end if;
end loop;
else
arr.extend();
arr(idx) := val;
end if;
end appendarr;
/
(The / character is required by some development tools to separate blocks, but is not part of the PL/SQL language itself.)
It seems the aim is to insert value val into element idx of array arr, shifting existing values up one place. However, it doesn't quite work:
declare
ar arr := arr('First', 'Second');
begin
appendarr
( arr => ar
, idx => 2
, val => 'New value' );
for i in ar.first..ar.last loop
dbms_output.put_line(i||' '||ar(i));
end loop;
end;
1 First
2 New value
3
Fixed version:
create or replace type varchar2_tt as table of varchar2(50)
/
create or replace procedure varchar2_tt_append
( arr in out varchar2_tt
, pos in pls_integer default null
, val in varchar2 )
as
idx pls_integer := nvl(pos,arr.last +1);
begin
if idx > arr.last then
arr.extend(idx - arr.last);
else
arr.extend();
for i in reverse greatest(idx,2)..arr.last loop
arr(i) := arr(i - 1);
end loop;
end if;
arr(idx) := val;
end varchar2_tt_append;
/
Test:
declare
ar varchar2_tt := varchar2_tt('First', 'Second', 'Third', 'Fourth');
begin
varchar2_tt_append
( arr => ar
, pos => 1
, val => 'New value' );
for i in ar.first..ar.last loop
dbms_output.put_line(i||' '||ar(i));
end loop;
end;
1 New value
2 First
3 Second
4 Third
5 Fourth

ORA-06502: PL/SQL: numeric or value error: character string buffer too small only three numbers

create or replace FUNCTION "FNC_CALCULATE_MOD11" (P_VALOR IN NUMBER)
return number is
Result number;
begin
DECLARE
-- LOCAL VARIABLES HERE
V_PROCESSO VARCHAR2(30);
V_PESO NUMBER := 2;
V_SOMA NUMBER := 0;
V_RESTO NUMBER := 0;
BEGIN
V_PROCESSO := TO_CHAR(P_VALOR);
WHILE LENGTH(V_PROCESSO) < 6 --Popular com zeros no inicio até 6
LOOP
V_PROCESSO := '0'||V_PROCESSO;
END LOOP;
--accuses error on this line
FOR I IN REVERSE 1 .. LENGTH(V_PROCESSO)
LOOP
V_SOMA := TO_CHAR (V_SOMA) + TO_NUMBER(SUBSTR(V_PROCESSO,i,1))*V_PESO;
IF V_PESO = 9 THEN --repetir peso se for necessario
V_PESO := 2;
ELSE
V_PESO := V_PESO + 1;
END IF;
END LOOP;
V_RESTO := MOD(V_SOMA, 11);
Result := 11 - V_RESTO;
IF ((Result = 0) OR (Result = 1) OR (Result >= 10)) THEN
Result := 1;
END IF;
END;
return(Result);
end FNC_CALCULATE_MOD11;
Try to change V_PROCESSO to a bigger size, for example V_PROCESSO VARCHAR2(300);

PL-00215: varchar2 length error

I'm trying to do a very simple thing: extract a date and do some controls on it.
Everything's fine but when I try to compile this error pops out and I really don't have a clue about how to solve it...
This is the code:
function get_crediti_formativi_biennio(p_userid varchar2,
p_prof_abil varchar2,
p_id_persona number,
p_tipo_formazione number,
p_anno_formazione varchar2,
p_flag_calcolo number,
p_crediti_totali out number)
return varchar2 is
v_count number;
v_anno varchar2;
v_biennio_from number;
v_biennio_to number;
l_err_msg varchar2(1024) := '+OK0000 Operazione effettuata con successo';
begin
v_count := null;
begin
select TO_CHAR(ap.valore)
into v_anno
from intc_attr_persone ap
where ap.id_attributo = 202
and ap.id = p_id_persona;
exception
when no_data_found then
v_anno := '';
end;
if v_anno >= 2015 and (mod(v_anno, 2) != 0) then
if (mod(p_anno_formazione, 2) = 0) then
v_biennio_from := p_anno_formazione;
v_biennio_to := p_anno_formazione + 1;
else
v_biennio_from := p_anno_formazione - 1;
v_biennio_to := p_anno_formazione;
end if;
else
if v_anno < 2015 or v_anno = '' or v_anno is null then
if (mod(p_anno_formazione, 2) = 0) then
v_biennio_from := p_anno_formazione - 1;
v_biennio_to := p_anno_formazione;
else
v_biennio_from := p_anno_formazione;
v_biennio_to := p_anno_formazione + 1;
end if;
end if;
end if;
The problem is on v_anno.....

I keep getting an error when trying to execute my code

Declare
Total integer;
i integer;
Begini:= 1;
total:=1;
loop
total := total * i;
i := i+1;
exit when i > 4;
End loop;
dbms_output.put_line('total is ' || total);
End;
For start
Begini:= 1;
total:=1;
Should be
Begin
i:= 1;
total:=1;

Unscramble string code in sql

I have a function in Oracle SQL which scrambles a given input. I need to unscramble it.
I need a program which can basically reverse the output of the program below.
source IN VARCHAR2
sGARBLED VARCHAR2(510);
index NUMBER;
length NUMBER;
onec NUMBER;
BEGIN
length := LENGTH(source);
IF length > 255 THEN
length := 255;
END IF;
index := 1;
sGARBLED := '';
WHILE index <= length LOOP
onec := ASCII(SUBSTR(source, index, 1)) - 30;
IF (onec < 10) THEN
sGARBLED := sGARBLED || '0';
END IF;
sGARBLED := sGARBLED || CAST(onec AS VARCHAR2);
index := index + 1;
END LOOP;
RETURN sGARBLED;
END
It can be possible, if you are only allowing character values in your original string before scrambling it, to be characters of the alphabet.
Code would look something like this:
sgarbled in VARCHAR2
UNsGARBLED VARCHAR2(255);
length NUMBER;
index NUMBER;
onec NUMBER;
BEGIN
length := LENGTH(sgarbled);
index := 1;
UNsGARBLED := '';
WHILE index <= length LOOP
onec := SUBSTR(sgarbled, index, 1);
IF (onec = '0') THEN
onec := SUBSTR(sgarbled, (index + 1), 1) + 30;
ELSE
onec := SUBSTR(sgarbled, (index), 2) + 30;
END IF;
UNsGARBLED := UNsGARBLED || CAST(CHR(onec) AS VARCHAR2);
index := index + 2;
END LOOP;
RETURN UNsGARBLED;
END
As Mr. Llama pointed out if you are allowing the original input string to contain all ASCII characters then it may not be possible.