Oracle PLSQL case statement - plsql

Why won't this CASE statement work in pl/sql? I'm trying to assign multiple values in one go. Is there a faster way to assign multiple values based on the below? Thanks.
DECLARE
x number := 5;
a CHAR;
b CHAR;
c CHAR;
BEGIN
CASE
WHEN x = 5 THEN a :='rx' AND b := 'rt' AND c :='ry';
WHEN ...
WHEN ...
END
END;

Try this:
DECLARE
x NUMBER := 5;
a VARCHAR2(2);
b VARCHAR2(2);
c VARCHAR2(2);
BEGIN
IF(x = 5)
THEN
a :='rx';
b := 'rt';
c :='ry';
END IF;
END;
You should use case keyword inside sql queries, but in this scenario when you want to set varaibels you need to use If Then Statement.

Related

what is program in plsql to check whether it is prime using function and procedure

declare
K number;
Lnumber;
f number;
function prime(n in number, I in number) return is flag
begin
i:=2;
flag:=1;
n:=&n;
for i in 2..n/2
loop
if mod(n,i)=0
then
flag:=0;
exit;
end if;
end loop;
if flag=1
then
dbms_output.put_line('prime');
else
dbms_output.put_line('not prime');
end if;
return flag;
end;
begin
k:=4;
L:=1;
f:= prime(n,i);
dbms_output.put_line(given number is ||flag);
end;
/
I am getting output as this I wonder what is wrong with my code:
Enter value for n: 4
old 9: n:=&n;
new 9: n:=4;
declare
*
ERROR at line 1:
ORA-06540: PL/SQL: compilation error
ORA-06553: PLS-906: Compilation is not possible
q2
SQL> DECLARE
num NUMBER;
3 c NUMBER;
4
5 PROCEDURE fact (x IN NUMBER, f OUT NUMBER)
6 IS
7 l_var NUMBER := 1;
8 BEGIN
9 FOR i IN 1 .. x
10 LOOP
11 l_var := l_var * i;
12 END LOOP;
13
14 f := l_var;
15 END;
16 BEGIN
17 num := 6;
18 fact (num, c);
19 DBMS_OUTPUT.put_line (' Factorial of ' || num || ' is ' || c);
20 END;
.
in this 2nd code the result is not getting displayed , not only for this even for other codes it is showing the line PL/SQL procedure successfully completed. but the results are not displaying what is wrong with it
A fixed version of q1 might be something like this (comments inline):
declare
-- k number; -- not used
-- l number; -- previously "lnumber;" not used anyway
f number;
function prime
( n in number ) -- "i" parameter never used
return number -- added return type
is
flag number := 1; -- added datatype, initial value and semicolon
begin
-- i := 2; -- Can't modify an IN parameter
-- flag := 1; -- not needed, can assign a value when declaring
-- n := &n; -- Can't modify an IN parameter
for i in 2 .. n / 2 loop
if mod(n, i) = 0 then
flag := 0;
exit;
end if;
end loop;
if flag = 1 then
dbms_output.put_line('prime');
else
dbms_output.put_line('not prime');
end if;
return flag;
end prime; -- added closing tag for clarity
begin
-- k := 4; -- not used
-- l := 1; -- not used
-- f := prime(n, i); -- n and i are not declared
f := prime(123);
dbms_output.put_line('prime check returns '|| f); -- added quotes, changed "flag" to "f"
end;
Also I formatted the code to make it more readable. This also helps when writing code, as it keeps the structure clearly visible and makes some errors more obvious.
q2 works for me, so you probably just need to check how whatever tool you are using displays dbms_output. In some tools there is a checkbox, others require a set server output on command.
You can also provide a function implementation of your factorial procedure:
declare
num number;
c number;
procedure fact
( num in number
, f out number )
is
begin
f := 1;
for i in 2 .. num loop
f := f * i;
end loop;
end fact;
function fact
( num number )
return number
is
f number;
begin
fact(num, f);
return f;
end fact;
begin
num := 6;
fact(num, c);
dbms_output.put_line('Factorial of ' || num || ' is ' || c);
dbms_output.put_line('Factorial of ' || num || ' is ' || fact(num));
end;

fibonacci series program using functions in pl/sql

I've to create a function which print the Fibonacci series as its result. I've used a varray in the program below but it is giving me an error saying "PLS-00201: identifier 'ARRAY' must be declared" on line no. 2.
create function fibonacci7(x int)
return VARRAY
is
type fib IS VARRAY(25) OF VARCHAR(10);
a number(3):=1;
b number(3):=1;
c number(3);
i number(3):=1;
begin
while a<=n
loop
fib(i) := a;
c:=a+b;
a:=b;
b:=c;
i:=i+1;
end loop;
return codes_;
end ;
/
select fibonacci7(5) from dual;
I think this will do what you want. VARRAY's have a little different syntax than what you were using.
set serveroutput on size 1000000
create or replace type fibtype AS VARRAY(25) OF NUMBER;
/
create or replace function fibonacci7(n number)
return fibtype
is
fib fibtype := fibtype();
a number:=1;
b number:=1;
c number;
i number:=1;
begin
fib.extend(n);
while i<=n
loop
fib(i) := a;
c:=a+b;
a:=b;
b:=c;
i:=i+1;
end loop;
return fib;
end ;
/
declare
i number;
fib fibtype := fibtype();
begin
fib := fibonacci7(6);
for i in 1..fib.count loop
dbms_output.put_line(to_char(fib(i)));
end loop;
end;
/
Here is the output.
1
1
2
3
5
8
Bobby
p.s. Fixed to work with fib(6) and made array numbers

Constraint Error running Heapify SiftDown

I am writing this code in Ada for a class where we have to teach ourselves the code. I understand heap sort, but the Ada syntax is really confusing me. I don't understand why I am getting a constraint error in this sort function.
Essentially we have to pass array "A" into this procedure, and it should organize it. I get the constraint error at siftDown(A(Start...A'Last));
Thank you in advance
Procedure sort_3(A : in out array_type) is
procedure swap(Left : in out Integer; Right : in out Integer) is
temp : Integer;
begin
temp := Left;
Left := Right;
Right := Temp;
end swap;
procedure siftDown(A : in out array_type) is
Count : Integer := 1;
root : Integer := Integer'Pos(A'First);
child : Integer := Integer'Pos(A'Last);
last : Integer := Integer'Pos(A'Last);
begin
while root * 2 + 1 <= last loop
child := root * 2 + 1;
if child + 1 <= last and then A(Integer'Val(child)) < A(Integer'Val(child + 1)) then
child := child + 1;
end if;
if A(Integer'Val(root)) < A(Integer'Val(child)) then
swap(A(Integer'Val(root)), A(Integer'Val(child)));
root := child;
else
exit;
end if;
end loop;
end siftDown;
procedure heapify(A : in out array_type) is
Count : Integer := 0;
First_Pos : Integer;
Last_Pos : Integer;
Start : Integer;
begin
First_Pos := A'First;
Last_Pos := A'Last;
Start := Integer'Val((Last_Pos - First_Pos + 1) / 2);
loop
siftDown(A(Start...A'Last));
if Start > Integer'First then
Start := Integer'Pred(Start);
else
exit;
end if;
end loop;
end heapify;
Last_Index : Integer := Integer'Last;
begin
heapify(A);
while Last_Index > Integer'First loop
swap(A(Last_Index), A(A'First));
Last_Index := Integer'Pred(Last_Index);
siftDown(A(A'First..Last_Index));
end loop;
end sort_3;
You have a syntax error in the code - an extra dot in A(Start...A'Last).
The syntax A(Start..A'Last) means a slice, part of array from Start to the last element. The Constraint_Error means that Start not in array bounds. Try to add
Ada.Text_IO.Put_Line (Start'Image);
before that line and you will see Start values and when it became out of the A'Range.
Your code has some references to Integer'First and Integer'Last, which are huge values that have nothing to do with the array A and its values. I'm pretty sure you should use A'First and A'Last instead.
Also a note on style: Using the same identifier, "A", for the parameter of the local (inner, nested) procedures as for the parameter "A" of the containing (outer) procedure, when these arrays can be different, invites confusion and errors. Better to use different identifiers.

generating prime numbers in pl/sql

Please tell me the problem in the code. I have written this code and its not working. Tell me the mistakes or if there is any other and easy method to generate prime numbers till 1000.
declare
i number;
prime number;
j number;
begin
for i in 2 .. 1000 loop
prime := 0;
for j in 2 .. i/2 loop
if mod(i,j)=0 then prime := 1
end if;
end loop;
if prime = 0 then dbms_output.put_line(i||'&');
end if;
end loop;
end;
You already have your answer (missing semicolon), but just for fun:
The i variable declared at the top is not used.
In theory j would be more efficient as a pls_integer (as i is implicitly). Possibly even a simple_integer, but then you'd need to restructure the loop to make i a simple_integer as well, and it's barely worth it for the tiny fraction of a second you might gain, if the compiler hasn't already optimised it.
You might as well exit the inner loop at the first match, rather than checking every single number.
prime would be more readable as a Boolean.
On the subject of readability, it is standard practice to align end loop under its opening loop statement.
I'm not seeing the point of appending & to every line of output.
This gives me:
declare
j pls_integer;
prime boolean;
begin
for i in 2 .. 1000 loop
prime := true;
for j in 2 .. i/2 loop
if mod(i,j) = 0 then
prime := false;
exit;
end if;
end loop;
if prime then
dbms_output.put_line(i);
end if;
end loop;
end;
You have missed one semicolon and try to put set server output on then run it
set serveroutput on
declare
i number;
prime number;
j number;
begin
for i in 2 .. 1000 loop
prime := 0;
for j in 2 .. i/2 loop
if mod(i,j)=0 then prime := 1;
end if;
end loop;
if prime = 0 then dbms_output.put_line(i||'&');
end if;
end loop;
end;
/

How do you get the square root in Ada?

So I have been given an assignment to read in a file put the numbers into two matrices, multiply the matrices, and finally put the output into a .txt file.
I have never used Ada before and I figured it would be a good challenge. I am stuck in trying to determine the bounds for the two separate arrays.
This is what I currently have:
currentSpread := I;
g := Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
while J < g loop
if(I mod J = 0) THEN
if(currentSpread > ((I/J - J)/2)) THEN
currentSpread := ((I/J - J)/2);
arrayBounds := J;
end if;
end if;
J := J + 1;
end loop;
The problem I am having is with the sqrt function. I want to find the factors for the best bounds of the matrix multiplication and this was the only way that I thought to implement it.
The error I am getting is:
invalid prefix in selected component "Ada.Numerics.Generic_Complex_Elementary_Functions"
Thanks a lot for any help.
--Update
Full Code as requested:
with Ada.Text_IO;use Ada.Text_IO;
with Ada.Integer_Text_IO;
with Ada.Numerics.Generic_Complex_Elementary_Functions;
with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Numerics.Complex_Elementary_Functions;
with Ada.Numerics.Generic_Complex_Types;
procedure Main is
dataFile : File_Type;
resultFile : File_Type;
value : Integer;
I : Integer := 0;
J : Integer;
currentSpread : Integer;
arrayBounds : Integer;
g : Integer;
begin
Ada.Text_IO.Open(File => dataFile, Mode => Ada.Text_IO.In_File, Name =>"C:\Users\Jeffrey\Desktop\data.txt");
while not End_Of_File(dataFile) loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Ada.Integer_Text_IO.Put(Item => value);
Ada.Text_IO.New_Line;
I := I + 1;
end loop;
Ada.Integer_Text_IO.Put(I);
I := I/2;
J := 1;
currentSpread := I;
g := Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
while J < g loop
if(I mod J = 0) THEN
if(currentSpread > ((I/J - J)/2)) THEN
currentSpread := ((I/J - J)/2);
arrayBounds := J;
end if;
end if;
J := J + 1;
end loop;
declare
type newArray is array(Integer range <>, Integer range<>) of Integer;
X : Integer := J;
Y : Integer := I/J;
Arr1 : newArray(1..Y, 1..X);
Arr2 : newArray(1..X, 1..Y);
finAnswer : newArray(1..X, 1..X);
begin
for z in 1 .. X loop
for k in 1 .. Y loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Arr1(z, k) := value;
end loop;
end loop;
for z in 1 .. Y loop
for k in 1 .. X loop
Ada.Integer_Text_IO.Get(File => dataFile, Item => value);
Arr2(z, k) := value;
end loop;
end loop;
for l in 1 .. X loop
for m in 1 .. Y loop
for n in 1 .. X loop
finAnswer(l, n) := finAnswer(l, n) + Arr1(l, n)* Arr2(n, m);
end loop;
end loop;
end loop;
end;
Ada.Text_IO.Close(File => dataFile);
end Main;
I am using the square root exclusively to figure out the factors of a number nothing else. How I have it set up now is it will go up to the square root and then it will take the smallest spread of the factors. I do not care about rounding errors or anything else if it isn't a perfect square it can round either way.
Thanks.
Generic_Complex_Elementary_Functions is a generic package. It cannot be used directly. That is why the compiler gives you an error on this line:
Ada.Numerics.Generic_Complex_Elementary_Functions.Sqrt(I);
To use it, you have to instantiate the generic Generic_Complex_Types with the floating-point type you want to use, and then instantiate Generic_Complex_Elementary_Functions with an instance of Generic_Complex_Types. Fortunately, you don't have to go through all that if you're willing to use the built-in type Float; the language provides Ada.Numerics.Complex_Elementary_Functions for you, that uses Float as the floating-point type, or Ada.Numerics.Long_Complex_Elementary_Functions that uses Long_Float if your compiler vendors support it.
However, I don't think you want to use Complex anything. That deals with complex numbers, and I doubt that you want to use those. Use Ada.Numerics.Elementary_Functions (or Long_Elementary_Functions), which deal with real numbers.
Finally, even this isn't going to work:
Ada.Numerics.Elementary_Functions.Sqrt(I)
if I is an integer, because the argument type needs to be a Float. You'll have to use a type conversion.
Ada.Numerics.Elementary_Functions.Sqrt(Float(I))

Resources