confused between dbms_output.put_line and dbms_output.put pl/sql - oracle

i was trying to make something like this
when input : 5
it will print
A B C D E
input : 10
print
A B C D E
J I H G F
input : 15
print
A B C D E
J I H G F
K L M N O
input : 20
A B C D E
J I H G F
K L M N O
T S R Q P
and so on...
here is my code i create
declare
angka number := '&Angka';
i number := trunc(angka/5);
p number := 65;
a number := 1;
b number := 1;
begin
while a <= b loop
if mod(i,2) = 1 then
a := 5;
for b in 1..5 loop
p := p + a
dbms_output.put( chr(p) || ' ' );
a := a - 1;
end loop;
p := p + 5;
else
a := 1;
for b in 1..5 loop
p := p + a
dbms_output.put( chr(p) || ' ' );
a := a + 1;
end loop;
end loop;
dbms_output.put_line(' ');
end;
/
but i was still confused it's still didn't work
and about dbms_output.put_line vs dbms_output.put can someone explain this ? because i was trying print using dbms_output.put it's didn't show.. i don't know why
Thanks

Firstly, the line p := p + a has not been terminated by semi-colon. Ideally, the PL/SQL anonymous block shouldn't compile at first place.
Secondly, with PUT procedure, you haven't completed the line yet. It needs GET_LINES to retrieve an array of lines from the buffer.
There was a similar question, Is dbms_output.put() being buffered differently from dbms_output.put_line()?

You have some problems in your code. I don't believe that you can execute exactly this code. Propably, you forgot to copy some parts of it.
First of all, syntax errors:
declare
angka number := '&Angka';
i number := trunc(angka/5);
p number := 65;
a number := 1;
b number := 1;
begin
while a <= b loop
if mod(i,2) = 1 then
a := 5;
for b in 1..5 loop
p := p + a -- ";" missed
dbms_output.put( chr(p) || ' ' );
a := a - 1;
end loop;
p := p + 5;
else
a := 1;
for b in 1..5 loop
p := p + a -- ";" missed
dbms_output.put( chr(p) || ' ' );
a := a + 1;
end loop;
-- here you missed "end if"
end loop;
dbms_output.put_line(' ');
end;
/
Also you don't need your outer loop ("while a <= b loop"), because its condition always is true and code execution will never ends. And last - when you declare
for b in 1..5 loop
oracle creates here new variable with name "b", and inside the loop previously declared b is not visible. Try to execute this:
declare
b number := 111;
begin
for b in 1..5 loop
dbms_output.put_line(b);
end loop;
dbms_output.put_line(b);
end;
/
You will get:
1
2
3
4
5
111
If you correct these errors, your code will work as you want.

Related

Pascal bubble sort print each sorted line

I have my bubble sorting algorithm which works correctly but I want to set it up so it prints each line in the process of the final output(19 lines).I have tried almost everything, but it doesn't print correctly:
program Bubble_Sort;
const N = 20;
var
d : array[1..N] of integer;
var
i,j,x : integer;
begin
randomize;
for i := 1 to N do d[i] := random(100);
writeln('Before sorting:'); writeln;
for i := 1 to N do write(d[i], ' ');
writeln;
for j := 1 to N - 1 do
for i := 1 to N - 1 do
write(d[i], ' ');
if d[i] > d[i+1] then
begin
x := d[i]; d[i] := d[i+1]; d[i+1] := x;
end;
writeln('After sorting:'); writeln;
for i := 1 to N do write(d[i], ' ');
writeln;
end.
The outer loop in the center of your code, the for j ... loop runs for each bubble iteration. That is where you want to output the state of the sorting. Because you thus have more than one statement within that for j ... loop, you must also add a begin .. end pair:
for j := 1 to N - 1 do
begin
//one round of sorting
//display result so far
end;
The sorting is ok as you have it, except when you added the write(d[i], ' '); presumably to output the sort result for one iteration, you changed the execution order to become totally wrong.
Remove the write(d[i], ' '); from where it is now.
To display the sorting result after each iteration add a new for k ... loop and a writeln;
for k := 1 to N do
write(d[k], ' ');
writeln;
Final sorting and progress display should be structured like:
for j := 1 to N - 1 do
begin
for i := 1 to N - 1 do
// one round of sorting
for k := 1 to N - 1 do
// output result of one sorting round
end;

Reading two dimensional pl/sql array

I am able to insert values but failed to retrieve values. Thanks in anticipation.
declare
type type1 is table of number;
type data_type is table of type1;
y data_type;
begin
y := data_type();
y.extend(100);
for i in 1..100 loop
y(i) := type1();
y(i).extend(100);
for j in 1..100 loop
y(i)(j) := i+j;
end loop;
end loop;
end;
If I understand well, you need a way to scan your arrays;
this could be a way:
declare
type type1 is table of number;
type data_type is table of type1;
y data_type;
k number := 2;
begin
y := data_type();
y.extend(k);
for i in 1..k loop
y(i) := type1();
y(i).extend(k);
for j in 1..k loop
y(i)(j) := i+j;
end loop;
end loop;
-- scanning
for i in y.first .. y.last loop
for j in y(i).first .. y(i).last loop
dbms_output.put_line('Y(' || i || ')(' || j || ') = ' || y(i)(j));
end loop;
end loop;
end;
the result:
Y(1)(1) = 2
Y(1)(2) = 3
Y(2)(1) = 3
Y(2)(2) = 4

How write a PL/SQL program that prints out string which looking like xml format

Input String : “a4b4c2d9d9c2e6e6b4s2o1o1s2a4w2r8r8k3g5g5k3w2”
I tried this code as first step:
declare
word varchar2(50) := 'a4b4c2d9d9c2e6e6b4s2o1o1s2a4w2r8r8k2g5g5k2w2';
num number := length(word)/2;
name_array dbms_sql.varchar2_table;
begin
dbms_output.put_line(word);
FOR i IN 1..num LOOP
name_array(i) := substr(word, -2*i, 2);
END LOOP;
FOR i IN name_array.FIRST .. name_array.LAST LOOP
dbms_output.put_line(name_array(i));
END LOOP;
end;
This code creates only an array of string. Not xml format. I need this output:
Which SQL functions,conditional clauses... do I need to use?
Oracle Setup:
CREATE OR REPLACE TYPE CHARS_TABLE IS TABLE OF CHAR(2);
/
CREATE OR REPLACE TYPE INTEGERS_TABLE IS TABLE OF INTEGER;
/
PL/SQL:
This assumes a well-formed set of character pairs and just indents each pair to the appropriate level:
DECLARE
word VARCHAR2(50) := 'a4b4c2d9d9c2e6e6b4s2o1o1s2a4w2r8r8k2g5g5k2w2';
num PLS_INTEGER := LENGTH( word ) / 2;
name_array CHARS_TABLE := CHARS_TABLE();
depth_array INTEGERS_TABLE := INTEGERS_TABLE();
open_array INTEGERS_TABLE := INTEGERS_TABLE();
BEGIN
name_array.EXTEND( num );
depth_array.EXTEND( num );
open_array.EXTEND( num );
name_array(1) := SUBSTR( word, 1, 2 );
depth_array(1) := 1;
open_array(1) := 1;
FOR i IN 2 .. num LOOP
name_array(i) := SUBSTR( word, 2*i - 1, 2 );
open_array(i) := 1;
FOR j IN 1 .. i-1 LOOP
IF name_array(j) = name_array(i) THEN
open_array(i) := -open_array(i);
END IF;
END LOOP;
depth_array(i) := depth_array(i-1) + open_array(i);
END LOOP;
FOR i IN 1 .. num LOOP
FOR j IN 2 .. depth_array(i) + CASE open_array(i) WHEN 1 THEN 0 ELSE 1 END LOOP
DBMS_OUTPUT.PUT( ' ' );
END LOOP;
DBMS_OUTPUT.PUT_LINE( name_array(i) );
END LOOP;
END;
/
Output:
a4
b4
c2
d9
d9
c2
e6
e6
b4
s2
o1
o1
s2
a4
w2
r8
r8
k2
g5
g5
k2
w2
Update - Simpler Stack-Based Version:
DECLARE
word CONSTANT VARCHAR2(50) := 'a4b4c2d9d9c2e6e6b4s2o1o1s2a4w2r8r8k2g5g5k2w2';
num CONSTANT PLS_INTEGER := LENGTH( word ) / 2;
name_array CHARS_TABLE := CHARS_TABLE();
depth PLS_INTEGER := 0;
name CHAR(2);
PROCEDURE indent( depth PLS_INTEGER, name CHAR )
IS
BEGIN
FOR j IN 2 .. depth LOOP
DBMS_OUTPUT.PUT( ' ' );
END LOOP;
DBMS_OUTPUT.PUT_LINE( name );
END;
BEGIN
name_array.EXTEND( num );
FOR i IN 1 .. num LOOP
name := SUBSTR( word, 2*i - 1, 2 );
IF depth > 0 AND name = name_array(depth) THEN
indent(depth,name);
depth := depth - 1;
ELSE
depth := depth - 1;
name_array(depth) := name;
indent(depth,name);
END IF;
END LOOP;
END;
/
DECLARE
vs_CurrentChar VARCHAR2(1);
vs_NextChar VARCHAR2(1);
vs_TempText VARCHAR2(100);
vs_InputText VARCHAR2(100) := 'abcdffdcba';
vn_LengthOfText NUMBER := 1;
vn_WhileIndex NUMBER := 1;
vs_Spaces VARCHAR(100);
BEGIN
vs_TempText := NULL;
vs_CurrentChar := substr(vs_InputText, vn_WhileIndex, vn_LengthOfText);
dbms_output.put_line(vs_CurrentChar);
WHILE vn_WhileIndex < length(vs_InputText) - 1 LOOP
vs_NextChar := substr(vs_InputText, vn_WhileIndex + 1, vn_LengthOfText);
EXIT WHEN vs_CurrentChar = vs_NextChar;
vs_TempText := vs_TempText || vs_CurrentChar;
vs_CurrentChar := vs_NextChar;
vs_Spaces := NULL;
FOR i IN 1 .. vn_WhileIndex LOOP
vs_Spaces := vs_Spaces || chr(9); --'*';
END LOOP;
dbms_output.put_line(vs_Spaces || vs_CurrentChar);
vn_WhileIndex := vn_WhileIndex + 1;
END LOOP;
dbms_output.put_line(vs_Spaces || vs_CurrentChar);
FOR i IN 1 .. length(vs_TempText) LOOP
vs_Spaces := substr(vs_Spaces, vn_LengthOfText, length(vs_Spaces) - 1);
vs_CurrentChar := substr(vs_TempText, -i, vn_LengthOfText);
dbms_output.put_line(vs_Spaces || vs_CurrentChar);
END LOOP;
END;
/
And output:
a
b
c
d
f
f
d
c
b
a
even, if you put '*'; instead of chr(9); then output will look like as:
a
*b
**c
***d
****f
****f
***d
**c
*b
a

PL/SQL Check Digit, luhn using MOD 11

So here is the question:
Write code to take in an id and determine if the check digit is correct
UPDATED CODE:
Set SERVEROUTPUT ON
DECLARE
val_num NUMBER := '&user_input';
holder NUMBER := 0;
y NUMBER := 0;
conv_string VARCHAR2(20);
BEGIN
conv_string := to_char(val_num*10);
for x in 1..length(conv_string) loop
y := to_number(substr(conv_string, -x, 1));
if mod(x,2) = 0 then
y := y * 2;
if y > 9 then
y := y - 9;
end if;
end if;
holder := holder + y;
end loop;
dbms_output.put_line ('Check is '||(11-Mod(holder, 11)));
END luhn;
/
SET SERVEROUTPUT ON
The return is:
SQL> # loop
Enter value for user_input: 036532
old 2: val_num NUMBER := '&user_input';
new 2: val_num NUMBER := '036532';
Check is 2
It should be 6
Before actual execution
SET SERVEROUTPUT ON
to enable SQL*Plus to fetch database output buffer.
Here is solution: https://community.oracle.com/thread/837639?start=0&tstart=0
There are lots of different variations of the luhn algorithm, so looking at these implementations and your (I think incomplete) description in the comments I think this may be fairly close to what you are looking for, and gives the correct checksum for 036532 as per your initial question.
Hope it is helpfull
Set SERVEROUTPUT ON
DECLARE
val_num number := '036532';
holder NUMBER := 0;
y NUMBER := 0;
conv_string VARCHAR2(20);
BEGIN
conv_string := to_char(val_num);
FOR X IN 1..LENGTH(CONV_STRING) LOOP
Y := TO_NUMBER(SUBSTR(CONV_STRING, -X, 1));
IF ((X+1) > 10) THEN
Y := Y * 10;
ELSE
Y := Y * (X + 1);
END IF;
IF (Y >= 10) THEN
HOLDER := HOLDER + TO_NUMBER(substr(TO_CHAR(Y), 1, 1)) + TO_NUMBER(substr(TO_CHAR(Y), 2, 1));
ELSE
HOLDER := HOLDER + Y;
END IF;
END LOOP;
HOLDER := MOD(HOLDER, 11);
Holder := 11 - mod(holder, 11);
dbms_output.put_line ('Check is '|| holder);
END luhn;
/
SET SERVEROUTPUT ON

All sums of a number

I need an algorithm to print all possible sums of a number (partitions).
For example: for 5 I want to print:
1+1+1+1+1
1+1+1+2
1+1+3
1+2+2
1+4
2+3
5
I am writing my code in Pascal. So far I have this:
Program Partition;
Var
pole :Array [0..100] of integer;
n :integer;
{functions and procedures}
function Minimum(a, b :integer): integer;
Begin
if (a > b) then Minimum := b
else Minimum := a;
End;
procedure Rozloz(cislo, i :integer);
Var
j, soucet :integer;
Begin
soucet := 0;
if (cislo = 0) then
begin
for j := i - 1 downto 1 do
begin
soucet := soucet + pole[j];
if (soucet <> n) then
Write(pole[j], '+')
else Write(pole[j]);
end;
soucet := 0;
Writeln()
end
else
begin
for j := 1 to Minimum(cislo, pole[i - 1]) do
begin
pole[i] := j;
Rozloz(cislo - j, i + 1);
end;
end;
End;
{functions and procedures}
{Main program}
Begin
Read(n);
pole[0] := 101;
Rozloz(n, 1);
Readln;
End.
It works good but instead of output I want I get this:
1+1+1+1+1
2+1+1+1
2+2+1
3+1+1
3+2
4+1
5
I can't figure out how to print it in right way. Thank you for help
EDIT: changing for j:=i-1 downto 1 to for j:=1 to i-1 solves one problem. But my output is still this: (1+1+1+1+1) (2+1+1+1) (2+2+1) (3+1+1) (3+2) (4+1) (5) but it should be: (1+1+1+1+1) (1+1+1+2) (1+1+3) (1+2+2) (1+4) (2+3) (5) Main problem is with the 5th and the 6th element. They should be in the opposite order.
I won't attempt Pascal, but here is pseudocode for a solution that prints things in the order that you want.
procedure print_partition(partition);
print "("
print partition.join("+")
print ") "
procedure finish_and_print_all_partitions(partition, i, n):
for j in (i..(n/2)):
partition.append(j)
finish_and_print_all_partitions(partition, j, n-j)
partition.pop()
partition.append(n)
print_partition(partition)
partition.pop()
procedure print_all_partitions(n):
finish_and_print_all_partitions([], 1, n)

Resources