oracle - PLS-00103 & ORA -06550 on procedures - oracle

I'm getting the above error while trying to run a simple PL/SQL program that uses procedures. I dont know what went wrong, please help out.
declare
create or replace procedure palindrome (x in number,y out number) is
i integer;
j integer;
k integer:=0;
begin
i:=x;
while i>0
loop
j:=mod(i,10);
k:=k*10+j;
i:=i/10;
end loop;
y:=k;
end;
begin
x integer:=121;
y integer;
palindrome(x,y);
dbms_output.put_line(y);
end;
/
ERROR at line 2:
ORA-06550: line 2, column 2: PLS-00103: Encountered the symbol
"CREATE" when expecting one of the following: begin function pragma
procedure subtype type current cursor delete exists prior

Modifications to your code.
create or replace procedure palindrome (x in number,y out number) is
i integer;
j integer;
k integer:=0;
begin
i:=x;
while i>0
loop
j:=mod(i,10);
k:=k*10+j;
i:=i/10;
end loop;
y:=k;
dbms_output.put_line(y);
end;
/
Execute that procedure
declare
y number;
begin
palindrome(133,y);
end;

You only need DECLARE when you're creating an anonymous PL/SQL block that contains variable declarations. When you're creating a named procedure/function/package, then your CREATE OR REPLACE ... statement takes the place of the DECLARE. Anything between that statement and the corresponding BEGIN is known as the declaration section.
It's not especially clear if you're trying to create a named procedure that you can then call with another PL/SQL anonymous block, in which case you'd do:
create or replace procedure palindrome (x in number,y out number) is
i integer;
j integer;
k integer:=0;
begin
i:=x;
while i>0
loop
j:=mod(i,10);
k:=k*10+j;
i:=i/10;
end loop;
y:=k;
end;
/
declare
x integer := 121;
y integer;
begin
palindrome(x,y);
dbms_output.put_line(y);
end;
/
or if you're trying to declare a procedure inside an anonymous PL/SQL, in which case you'd do:
declare
x integer := 121;
y integer;
procedure palindrome (x in number, y out number) is
i integer;
j integer;
k integer := 0;
begin
i := x;
while i > 0
loop
j := mod(i,10);
k := k*10 + j;
i := i/10;
end loop;
y := k;
end palindrome;
begin
palindrome(x,y);
dbms_output.put_line(y);
end;
/

Related

Not understanding array merging procedure in merge sort procedure

I've been trying to learn the procedure for merging two arrays in merge sort, and I've been given a fixed code which I have to strictly follow .The following is a program for sorting a list of numbers in ascending/ descending order depending on the user's choice is as follows:
const
max = 200000;
MaxDisp = 20;
type
list = array[1..max] of real;
var
a: list;
na: longint;
is_asc:boolean;
procedure GenList(var L: list; n: longint);
var
i: longint;
begin
randomize;
for i := 1 to n do begin
L[i] := random;
end;
end;
procedure DispList(L: list; n: longint);
var
i: longint;
begin
for i := 1 to MaxDisp do begin
if i <= n then begin
writeln(i:10, ' - ', L[i]:0:10);
end;
end;
if n > MaxDisp then begin
writeln(n - MaxDisp, ' more ...');
end;
end;
procedure sort(var L: list; n: longint;is_asc:boolean);
procedure Merge(L1,L2,R1,R2:longint);
var
M:list;//this is C
i1,i2,iM,i,j:longint;
begin
i1:=L1;
i2:=L2;
j:=1;
while (i1<=R1) and (i2<=R2) do begin
if (is_asc and (L[i1]<L[i2])) or not is_asc and (L[i1]<L[i2]) then begin
M[j]:=L[i1];
j:=j+1;
i1:=i1+1;
end
else begin
M[j]:=L[i2];
j:=j+1;
i2:=i2+1;
end;
j:=________;
end;
if(i1>R1) and (i2<=R2) then
for i:=________ do begin
M[j]:=_______;
end
else if (i2>R2) and (i1<=R1) then
for i:=1 to _______ do begin
_________;
end;
num:=_______;
i:=______;
for j:=1 to num do begin
_________;
end
end;
procedure MSort(LL,RR:longint);
var mid:integer;
begin
if LL<RR then begin
mid:=(LL+RR) div 2;
MSort(LL,mid);
MSort(mid+1,RR);
Merge(LL,mid,mid+1,RR);
end
end;
begin
MSort(1,n);
end;
function is_sorted(L: list; n:longint;is_asc:boolean): boolean;
var
i: longint;
flag: boolean;
begin
flag := true;
i := 1;
while flag and (i < n) do begin
flag := ((L[i]<=L[i+1]) and (is_asc)) or (not(is_asc) and (L[i]>=L[i+1]));
i := i + 1;
end;
is_sorted := flag;
end;
begin
na := MaxDisp;
GenList(a, na);
writeln(na, ' random items:');
DispList(a, na);
writeln('Press <Enter> to sort the list in ascending order ...');
readln;
sort(a, na,is_asc);
DispList(a, na);
writeln('Sorted in ascending order: ', is_sorted(a, na,is_asc));
write('Press <Enter> to continue ...');
readln;
end.
Except for the blank parts, I understand what the other parts of the code are doing, including the first part of the procedure Merge, which I think is just merging the arrays in L into M, and I think the following part is writing about the cases in case i1 and i2 are larger than L1 and L2, but I don't understand what the problem if this happens or what should be done. After this the following parts of the procedure Merge I have no idea what it is supposed to be doing.
I don't know this language (indexes start at 1?), but this is what I think needs changing:
i1:=L1;
i2:=L2;
j:=1;
while (i1<=R1) and (i2<=R2) do begin
if (is_asc and (L[i1]<L[i2])) or not is_asc and (L[i1]<L[i2]) then begin
M[j]:=L[i1];
j:=j+1;
i1:=i1+1;
end
else begin
M[j]:=L[i2];
j:=j+1;
i2:=i2+1;
end;
// j:=________; // don't change j
end;
while(i1 <= R1) do begin // copy rest of run 1 if any elements
M[j]:=L[i1];
j:=j+1;
i1:=i1+1;
end
while(i2 <= R2) do begin // copy rest of run 2 if any elements
M[j]:=L[i2];
j:=j+1;
i2:=i2+1;
end
for(i = 1 to j) do begin // copy M back into L
L[i+L1-1] := M[j]; // I'm not sure about the -1
end
end;

plsql procedure is not a procedure or is undefined

I want to create a plsql procedure to calculate the factorial of a given number.
This is the procedure:
CREATE OR REPLACE PROCEDURE fact(x IN number, fact OUT number)
IS
BEGIN
while x > 0 loop
fact := x*fact;
x := x-1;
END loop;
END;
/
Warning: Procedure created with compilation errors.
and this is where I'm calling the function
DECLARE
x number := &x;
fact number := 1;
BEGIN
fact(x,fact);
dbms_output.put_line('Factorial is: '||fact);
END;
and this is the error I'm getting:
Enter value for x: 5
old 2: x number := &x;
new 2: x number := 5;
fact(x,fact);
*
ERROR at line 5:
ORA-06550: line 5, column 1:
PLS-00221: 'FACT' is not a procedure or is undefined
ORA-06550: line 5, column 1:
PL/SQL: Statement ignored
You need to convert your creation of procedure like this :
SQL> CREATE OR REPLACE PROCEDURE fact(x IN OUT number, fact OUT number) IS
BEGIN
while x > 0 loop
fact := x * nvl(fact, 1);
x := x - 1;
END loop;
END;
/
and call :
SQL> SET SERVEROUTPUT ON;
SQL> DECLARE
x number := &x;
v_fact number := 1;
BEGIN
fact(x, v_fact);
dbms_output.put_line('Factorial is: ' || v_fact);
END;
Factorial is: 120
You can not use a variable of type IN as an assignment target
You need to initialize a null variable fact as nvl(fact,1) or fact := 1; just before the while x > 0
Actually, you even do not need an extra parameter fact OUT number for procedure named fact, and make that as local. So, your procedure may be replaced with this :
SQL> CREATE OR REPLACE PROCEDURE fact(x IN OUT number) IS
fact number := 1;
BEGIN
while x > 0 loop
fact := x * fact;
x := x - 1;
end loop;
x := fact;
END;
/
Therefore, should be invoked as :
SQL> DECLARE
x number := &x;
BEGIN
fact(x);
dbms_output.put_line('Factorial is: ' || x);
END;
Factorial is: 120
You might consider rewriting this as a function along the lines of the following:
CREATE OR REPLACE FUNCTION fact(pinX IN INT)
RETURN INT
IS
nResult INT := 1;
BEGIN
FOR i IN 2..pinX LOOP
nResult := i * nResult;
END LOOP;
RETURN nResult;
END FACT;
dbfiddle here
Best of luck.

Pascal error: left side cannot be assigned when trying to compile

I got this error when trying to compile.
left side cannot be assign to, ./number 21,22 in pastebin
here is my code
Program urut;
Uses Wincrt;
Const N = 5;
data: Array [1..N] Of Integer = (2,4,5,3,1);
Var
j,k,temp : Integer;
Begin
Clrscr;
Writeln ('Data sebelum diurutkan');
For j:=1 To N Do
Begin
Writeln('data[' ,j, ']= ',data [j]);
End;
For j:=1 To N-1 Do
Begin
For k :=N Downto j+1 Do
Begin
If data[k] < data[k-1] Then
Begin
temp := data[k];
data[k] := data[k-1]; //left side cannot be assigned to
data[k-1] := temp; //left side cannot be assigned to
End;
End;
End;
Writeln;
Writeln ('Data setelah diurutkan ');
For j:=1 To N Do
Begin
Writeln ('data[' ,j, '] = ',data[j]);
End;
Writeln;
End.
sorry for uncorrectly pattern post
, thank you so much.
Like tom Tom Brunberg says, my array is const, it can't be changed. Therefore I need to remove that const.
So it should be
data: Array [1..5] Of Integer = (value);
without const, and put it under var with another variable

factorial of a number in pl/sql

The following pl/sql program generates an error on execution on line the sum :=temp*sum; encountered symbol ; when expecting ( . Please explain my mistake.
declare
n number;
temp number;
sum number := 1;
begin
n := &n;
temp := n;
while temp>0 loop
sum := temp*sum;
temp := temp-1;
end loop;
dbms_output.put_line('Factorial of '||n||' is '||sum);
end;
/
Maybe not the answer to your question, but there is no need for PL/SQL here:
select round(exp(sum(ln(level))))
from dual
connect by level <= 5;
where 5 is your number (5!).
Additionally, if you like to operate faster in PL/SQL use pls_integer instead of number.
UPDATE
So according to comments I felt free to test:
create or replace package test_ is
function by_query(num number) return number deterministic;
function by_plsql(num number) return number deterministic;
end test_;
/
create or replace package body test_ is
function by_query(num number) return number deterministic
is
res number;
begin
select round(exp(sum(ln(level))))
into res
from dual
connect by level <= num;
return res;
end;
function by_plsql(num number) return number deterministic
is
n number := 0;
begin
for i in 1..num loop
n := n + ln(i);
end loop;
return round(exp(n));
end;
end test_;
So there are two functions with different content. Test query:
declare
dummy number;
begin
for i in 1..10000 loop
dummy := test_.by_query(5);
end loop;
end;
0.094 sec.
declare
dummy number;
begin
for i in 1..10000 loop
dummy := test_.by_plsql(5);
end loop;
end;
0.094 sec.
You'll say I am cheater and using deterministic keyword but here it is obvious and is needed by logic. If I remove it, the same scripts are working 1.7 sec vs 1.3 sec, so procedure is only a bit faster, there is no even double-win in performance. The totally opposite effect you will get if you use the function in a query so it is a fair trade.
Sum is reserved word in sql. Change variable name like
declare
n number;
temp number;
sum_ number := 1;
begin
n := &n;
temp := n;
while temp>0 loop
sum_ := temp*sum_;
temp := temp-1;
end loop;
dbms_output.put_line('Factorial of '||n||' is '||sum_);
end;
/
declare
n number;
i number;
sum_of_log_10s number;
exponent number;
base number;
begin
n := &n;
i := 1;
sum_of_log_10s := 0;
while i <= n loop
-- do stuff
sum_of_log_10s := sum_of_log_10s + log(10,i);
i := i + 1;
end loop;
dbms_output.put_line('sum of logs = '||sum_of_log_10s);
exponent := floor(sum_of_log_10s);
base := power(10,sum_of_log_10s - exponent);
dbms_output.put_line(n||'! = '||base||' x 10^'||exponent);
end;
I came up with this code that I like even better than #smnbbrv's answer. It's a great way to check the speed of a machine. I've been using a variation of this since my Atari 800
ALTER SESSION FORCE PARALLEL DDL PARALLEL 16;
ALTER SESSION FORCE PARALLEL DML PARALLEL 16;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 16;
with t as (
select /*+materialize*/
rownum i
from dual connect by rownum < 100000 -- put number to calculate n! here
)
,t1 as (
select /*+parallel(t,16)*/ /*+materialize*/
sum(log(10,i)) logsum
from t
)
select
trunc(power(10,(mod(logsum,1))),3) ||' x 10^'||trim(to_char(floor(logsum),'999,999,999,999')) factorial
-- logsum
from t1
;
-- returns 2.824 x 10^456,568
Here is the simple code for finding factorial of number at run time...
declare
-- it gives the final answer after computation
fac number :=1;
-- given number n
-- taking input from user
n number := &1;
-- start block
begin
-- start while loop
while n > 0 loop
-- multiple with n and decrease n's value
fac:=n*fac;
--dbms_output.put(n||'*');
n:=n-1;
end loop;
-- end loop
-- print result of fac
dbms_output.put_line(fac);
-- end the begin block
end;

small problem In Pascal , Could you please help?

I write this program with pascal
which ask the user to enter two arrays and constant value which is K
the program muli the K with arrays .
and then save the answer in new array
and do some operation in new array
addition << work well
Subtraction << also work
BUT the problem in Multi << I am trying to ask the user to enter a new array and do Muti but still there is a problem.
ALSO
I want these operation repeated until the user press exit <<< I could not do this options because i am not perfect with pascal .
I would be grateful if you could help me
This is My Code
program BST6;
const maxN=100;maxM=100;
type mat=array[1..maxN,1..maxM]of integer;
var A,B,c:mat;
n,m,l,s,i,j,k:integer;
ch : char;
procedure readMat(var A:mat;var m,n:integer);
begin
for i:=1 to m do
for j:=1 to n do
begin
write('mat[',i,',',j,']=');
readln(A[i,j]);
end;
end;
procedure writeMat(A:mat;m,n:integer);
begin
for i:=1 to m do
begin
for j:=1 to n do
write(a[i,j]:4);
writeln;
end;
end;
function multK(A:mat;k:integer):mat;
begin
for i:=1 to n do
for j:=1 to m do
begin
B[i,j]:= K*A[i,j];
end;
multK:=B;
end;
function minus(A,B:mat):mat;
begin
for i:=1 to m do
for j:=1 to n do
C[i,j]:=A[i,j]-B[i,j];
minus:=C;
end;
function plus(A,B:mat):mat;
begin
for i:=1 to m do
for j:=1 to n do
C[i,j]:=A[i,j]+B[i,j];
plus:=C;
end;
function mult(A,B:mat;m,l,n:integer):mat;
begin
for i:=1 to m do
for j:=1 to n do
for k:=1 to l do
c[i,j]:=c[i,j]+A[i,k]*B[k,j];
mult:=C;
end;
begin
write('input m<=',maxM,'.. m=' );readln(m);
write('input n<=',maxN,'.. n=');readln(n);
readMat(A,m,n);
writeln('input the const K');readln(k);
B:=multK(A,K);
writeln('The matrix A : ');
writeMat(A,m,n);
writeln('The matrix B=K*A : ');
writeMat(B,m,n);
writeln('choose the operation + , - or * ');
readln(ch);
case ch of
'+' : c:=plus(A,B);
'-' : c:=minus(A,B);
'*' : begin
writeln('input m<=',maxM,'input l<=',maxN);readln(m,l);readMat(A,m,l);
writeln('input l<=',maxN);readln(n);readMat(B,l,n);
c:=mult(A,B,m,l,n);
end;
end;
writeMat(c,m,n);
readln;
end.
First of all having global one letter variables which collide with function parameters with the same name is insane.
Why does multK modify the global variable B as a sideeffect?
Why does minus modify the global variable C as a sideeffect?
Why global integers as for index variables?
And mult is even worse: It doesn't only modify C as a sideeffect, but it assumes C contains meaningful values beforehand. I think it needs to initialize C to all zeros beforehand.
My guess is some of your side effects interfere in strange ways. But I don't want to think it through. Refactor your code first. In particular learn how and when to use local variables.

Resources