I had generate 1 round numbers:
set serveroutput on
declare
i number(9);
x number(9) := 0;
begin
for i in 0..7 loop
DBMS_OUTPUT.PUT_LINE(x);
x:=x+1;
end loop;
end;
Result is: 0, 1, 2, 3....7
My next round should generate numbers: 10, 11, 12....17
Total output should looks as below:
0 1 2 3 4 5 6 7
10 11 12 13 14 15 16 17
20 21 22 23 24 25 26 27
...
80 81 82 83 84 85 86 87
How can I jump 3 between each round? I will increase my counter till 81.
set serveroutput on
declare
i number(9);
y number(9);
x number(9) := 0;
z number(9) := 0;
begin
for y in 0..8 loop
for i in 0..7 loop
DBMS_OUTPUT.PUT_LINE(x);
x := z+i+1;
end loop;
z := z + 10;
x := z;
end loop;
end;
Looks like you want to output 9 times 7 numbers. That is one loop running 9 times and inside a loop that runs 7 times, I'd say. E.g.
begin
for i in 0..8 loop
for j in 0..7 loop
dbms_output.put(i * 10 + j);
dbms_output.put(' ');
end loop;
dbms_output.put_line('');
end loop;
end;
How about such a WHILE loop?
SQL> set serveroutput on
SQL> declare
2 i number := 0;
3 begin
4 while i < 30
5 loop
6 dbms_output.put_line (i);
7
8 i := i + case when substr (to_char (i), -1) >= 7 then 3 else 1 end;
9 end loop;
10 end;
11 /
0
1
2
3
4
5
6
7
10
11
12
13
14
15
16
17
20
21
22
23
24
25
26
27
PL/SQL procedure successfully completed.
SQL>
The Logic is: if i mod 10 = 7 then increment by 3 otherwise increment by one. Thus,
set serveroutput on
declare
i number(9);
x number(9) := 0;
begin
for i in 0..100 loop
DBMS_OUTPUT.PUT_LINE(x);
IF mod(i,10) = 7 THEN
x := x +3;
ELSE
x:=x+1;
END IF;
end loop;
end;
Related
I cant compile this PL/SQL stored function successfully. Cant find a right way to do it..
CREATE OR REPLACE FUNCTION calGrade
(
cmark IN student.mark%TYPE
)
RETURN VARCHAR2
IS
comment VARCHAR2(10);
BEGIN
IF cmark := 1 THEN comment := 'Very Poor';
ELSIF cmark := 2 THEN comment := 'Poor';
ELSIF cmark := 3 THEN comment := 'Moderate';
ELSIF cmark := 4 THEN comment := 'Good';
ELSIF cmark := 5 THEN comment := 'Excellent';
END IF;
RETURN comment;
END;
/
Remove colon from all IFs.
SQL> CREATE OR REPLACE FUNCTION calGrade (cmark IN student.mark%TYPE)
2 RETURN VARCHAR2
3 IS
4 comment VARCHAR2 (10);
5 BEGIN
6 IF cmark = 1
7 THEN
8 comment := 'Very Poor';
9 ELSIF cmark = 2
10 THEN
11 comment := 'Poor';
12 ELSIF cmark = 3
13 THEN
14 comment := 'Moderate';
15 ELSIF cmark = 4
16 THEN
17 comment := 'Good';
18 ELSIF cmark = 5
19 THEN
20 comment := 'Excellent';
21 END IF;
22
23 RETURN comment;
24 END;
25 /
Function created.
SQL>
How about using a case expression instead?
comment := (CASE cmark
WHEN 1 THEN 'Very Poor'
WHEN 2 THEN 'Poor'
WHEN 3 THEN 'Moderate'
WHEN 4 THEN 'Good'
WHEN 5 THEN 'Excellent'
END);
I can't seem to use DBMSRAND.
GRANT EXECUTE ON DBMS_RANDOM TO *schema*;
ORA-01031: insufficient priveleges
Not sure why as I'm using the DBadmin schema to grant, but does anyone have a work around for random number generation in oracle sql?
If you're really desperate you could roll your own, eg here's an LG one
SQL> create or replace
2 package global is
3 a number := to_number(to_char(systimestamp,'FF'));
4 end;
5 /
Package created.
SQL>
SQL> create or replace
2 function rand(r in number) return number is
3
4 mill constant number:=100000000;
5 ten_thou constant number:=10000;
6 lg_num constant number:=31415821;
7
8 v number;
9 w number;
10 x number;
11 y number;
12 z number;
13
14 begin
15 w:=trunc(global.a/ten_thou);
16 x:=mod(global.a,ten_thou);
17 y:=trunc(lg_num/ten_thou);
18 z:=mod(lg_num,ten_thou);
19 v := mod((mod(x*y+w*z,ten_thou)*ten_thou+x*z),mill);
20 global.a:=mod(v+1,mill);
21 return(trunc((trunc(global.a/ten_thou)*r)/ten_thou));
22 end;
23 /
Function created.
SQL>
SQL> select rand(100) from dual;
RAND(100)
----------
21
SQL> select rand(100) from dual;
RAND(100)
----------
72
SQL> select rand(100) from dual;
RAND(100)
----------
1
SQL> select rand(100) from dual;
RAND(100)
----------
43
but random number generation is a science so you should be aware of the all of the limitations and drawbacks of rolling your own.
https://en.wikipedia.org/wiki/Linear_congruential_generator
So your best bet is to get appropriate access to the appropriate packages.
SQL> DECLARE
2 SEL NUMBER(3);
3 ans VARCHAR(20);
4 BEGIN:
5 SEL := &SEL ;
6 CASE SEL
7 WHEN 1 THEN ans := 'SUNDAY';
8 WHEN 2 THEN ans := 'MONDAY';
9 WHEN 3 THEN ans := 'TUESDAY';
10 WHEN 4 THEN ans := 'WEDNESDAY';
11 WHEN 5 THEN ans := 'THURSDAY';
12 WHEN 6 THEN ans := 'FRIDAY';
13 WHEN 7 THEN ans := 'SATURDAY';
14
15 END CASE;
16 DBMS_OUTPUT.PUT_LINE(' CORRESPONDING DAY FOR THE NUMBER '||SEL||' IS '||DAY);
17 END;
18 /
Enter value for sel: 3
old 5: SEL := &SEL ;
new 5: SEL := 3 ;
SP2-0552: Bind variable "SEL" not declared.
There are two problems in your block:
There is a colon after BEGIN, it's not supposed to be there
In your output there is a the DAY variable that is not declared, it should be the variable ans.
Below is the working version:
DECLARE
SEL NUMBER(3);
ans VARCHAR(20);
BEGIN
SEL := &SEL ;
CASE SEL
WHEN 1 THEN ans := 'SUNDAY';
WHEN 2 THEN ans := 'MONDAY';
WHEN 3 THEN ans := 'TUESDAY';
WHEN 4 THEN ans := 'WEDNESDAY';
WHEN 5 THEN ans := 'THURSDAY';
WHEN 6 THEN ans := 'FRIDAY';
WHEN 7 THEN ans := 'SATURDAY';
END CASE;
DBMS_OUTPUT.PUT_LINE(' CORRESPONDING DAY FOR THE NUMBER '||SEL||' IS '||ans);
END;
/
I have the following table
icode iname icatcode slno
10 a 11 0
20 b 31 0
30 c 11 0
40 d 21 0
50 e 31 0
60 f 11 0
70 g 21 0
80 h 41 0
I need to update the slno column using cursor.
The output should be the following table ie., when the icatcode is same it should increment the slno & wen icatcode changes it should set the slno to 1
icode iname icatcode slno
10 a 11 1
30 b 11 2
60 c 11 3
70 d 21 1
40 e 21 2
50 f 31 1
20 g 31 2
80 h 41 1
I have written the query for it
declare #icode int,#iccode int, #islno int,#inccode int
set #islno=1
declare cur2 cursor for select icode,iccode from im
order by iccode
open cur2
fetch next from cur2 into #icode,#iccode
while ##FETCH_STATUS=0
begin
update im set slno=#islno where #icode=icode
fetch next from cur2 into #icode,#inccode
if #iccode<>#inccode
begin
set #islno=1
end
else
begin
set #islno=#islno+
end
end
close cur2
deallocate cur2
The above query results in the following output
icode iname icatcode slno
10 a 11 1
20 b 31 1
30 c 11 2
40 d 21 1
50 e 31 1
60 f 11 3
70 g 21 1
80 h 41 1
What changes do I need so that I will get the desired output?
NOTE: We should solve this only using "CURSORS" in sql 2008
I need to convert a number to another value based on a range:
ie:
7 = "A"
106 = "I"
I have a range like this:
from to return-val
1 17 A
17 35 B
35 38 C
38 56 D
56 72 E
72 88 F
88 98 G
98 104 H
104 115 I
115 120 J
120 123 K
123 129 L
129 infinity M
The values are fixed and do not change.
I was thinking a lookup table would be required, but is there a way it could be done with a function on an analytics function inside of oracle?
Think I would use a mapping table:
mapping:
to ret
17 A
38 B
Select Max(ret)
From mapping
Where x <= to
You could also use CASE WHEN:
Select Case When x <= 17 Then 'A'
When x <= 35 Then 'B'
When x <= 38 Then 'C'
...
Else 'M' End
From your_table
SQL servers are designed such that operating on a table is faster than anything else -- particularly when that table will only have 13 rows.
I would create a function, in oracle, since it should be more efficient than doing a table lookup (no roundtrip to disk will ever be involved).
CREATE OR REPLACE Function ValueFromRange
( n IN number )
RETURN varchar2
IS
ret varchar2;
BEGIN
ret := -1; -- UNDEFINED?
IF n >= 1 and n <= 17 THEN
ret := 'A';
ELSIF n >= 18 and n <= 35 THEN
ret := 'B';
ELSIF n >= 36 and n <= 38 THEN
ret := 'C';
ELSIF n >= 39 and n <= 56 THEN
ret := 'D';
ELSIF n >= 57 and n <= 72 THEN
ret := 'E';
ELSIF n >= 73 and n <= 88 THEN
ret := 'F';
ELSIF n >= 89 and n <= 98 THEN
ret := 'G';
ELSIF n >= 99 and n <= 104 THEN
ret := 'H';
ELSIF n >= 105 and n <= 115 THEN
ret := 'I';
ELSIF n >= 116 and n <= 120 THEN
ret := 'J';
ELSIF n >= 121 and n <= 123 THEN
ret := 'K';
ELSIF n >= 124 and n <= 129 THEN
ret := 'L';
ELSIF n >= 130 THEN
ret := 'M';
END IF;
RETURN ret;
END;