Get output from array in Ada - ada

I want to print array data user input.
But it give me error. I need to get input from user and store in the array. After this i want to print it also count each duplicate word.
with Ada.Text_IO;
use Ada.Text_IO;
procedure Main is
type String_Val is array (1 .. 100) of Character;
type Int_Val is array (1 .. 100) of Integer;
Data : String_Val;
begin
Put_Line ("Please enter values (use space as seperator)");
for I in 1..String_Val'Length loop
Data(I) := Character'Value(Get_Line);
end loop;
for I in String_Val'Range loop
Put (String_Val (Data));
end loop;
end Main;

The following program reads a string as input, tallies the occurrences of characters in the string and outputs both the input string and the occurrences of each character in the input string.
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type Character_Counts is array (Character) of Natural;
Input : String (1 .. 100); -- String is an array of Character;
Counts : Character_Counts := (Others => 0);
Length : Natural;
begin
Put_Line("Enter a string:");
Get_Line(Item => Input,
Last => Length);
Put_Line ("You entered:");
-- output the data entered by the user
Put_Line(Input(1..Length));
-- Count character occurrences in the string
for I in 1 .. Length loop
Counts(Input(I)) := Counts(Input(I)) + 1;
end loop;
-- output counts of characters in the string
for C in Counts'Range loop
if Counts(C) > 0 then
Put_Line(Character'Image(C) & " : " & Counts(C)'Image);
end if;
end loop;
end Main;
Type Character_Counts is an array of Natural indexed by all the values of type Character. Natural is a pre-defined subtype of integer with a minimum value of 0. The variable Counts is an instance of Character_Counts with all its elements initialized to 0.
The Get_Line procedure returns the string you passed in, filled with characters up to the length of the string or the number of characters entered. The variable Length contains the number of characters entered by the user.
When counting the occurrences of the characters in the string the each character of the string is used as an index into the variable Counts, and the corresponding element in Counts is incremented.
A sample execution of this program is:
Enter a string:
This is a test.
You entered:
This is a test.
' ' : 3
'.' : 1
'T' : 1
'a' : 1
'e' : 1
'h' : 1
'i' : 2
's' : 3
't' : 2

Related

How do I rectify this switch case error in Ada?

with Ada.Text_IO; use Ada.Text_IO;
procedure factor is
rate: Integer;
begin
Put("Enter rate: ");
Get(rate);
case rate is
when 1 | 2 =>
Put("Factor =", factor = 2 * rate - 1);
when 3 | 5 =>
Put("Factor =", factor = 3 * rate + 1);
when 4 =>
Put("Factor =", factor = 4 * rate - 1);
when 6 | 7 | 8 =>
Put("Factor =", factor = rate - 2);
when others =>
Put("Factor =", rate);
end case;
end factor;
I am new to ada and im not able to resolve this error. please help me with this code
this is a simple switch case in ada.. this should return factor and rate is the input from user
Here is a comparison of your program and one that compiles and works correctly:
---------------------------------------------------------------
-- Original program:
--
-- with Ada.Text_IO; use Ada.Text_IO;
-- procedure factor is
-- rate: Integer;
-- begin
-- Put("Enter rate: ");
-- Get(rate);
-- case rate is
-- when 1 | 2 =>
-- Put("Factor =", factor = 2 * rate - 1);
-- when 3 | 5 =>
-- Put("Factor =", factor = 3 * rate + 1);
-- when 4 =>
-- Put("Factor =", factor = 4 * rate - 1);
-- when 6 | 7 | 8 =>
-- Put("Factor =", factor = rate - 2);
-- when others =>
-- Put("Factor =", rate);
-- end case;
-- end factor;
------------------------------------------------------------------
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Main is
rate : Integer;
factor : Integer;
begin
Put ("Enter rate: ");
Get (rate);
case rate is
when 1 | 2 =>
factor := 2 * rate - 1;
when 3 | 5 =>
factor := 3 * rate + 1;
when 4 =>
factor := 4 * rate - 1;
when 6 | 7 | 8 =>
factor := rate - 2;
when others =>
factor := rate;
end case;
Put_Line ("Factor =" & factor'Image);
end Main;
In Ada I/O procedures and functions are tied to the types being read or written. Therefore, reading an Integer requires an instance of Ada.TextIO.Integer_IO. The predefined package Ada.Integer_Text_IO is just such a package. The Get procedure from that package is used to input the value for the rate variable.
In Ada variables must be declared before they are used and they are only declared in the declarative part of a procedure or function; that is, the part of the procedure or function before the reserved word begin. The variable named factor is declared in the declarative part of the procedure main.
The case statement calculates the value of factor based upon the rate input. After the end of the case statement the variable factor has been assigned a value according to the logic in the case statement. It is then output with a trailing newline character using the Put_Line procedure.
The Put_Line procedure requires a single string for its argument. That string is created by concatenating a literal string "Factor =", with the string representation of the value in factor. The 'Image attribute converts the integer value in factor to its corresponding string representation. That string value is concatenated with the literal string forming a single string argument for the Put_Line procedure.
First of all, you did not mention the error you got.
I think you got this first
factor.adb:8:05: no candidate interpretations match the actuals:
factor.adb:8:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:239
factor.adb:8:05: missing argument for parameter "Item" in call to "get" declared at a-textio.ads:205
factor.adb:8:09: expected type "Standard.String"
factor.adb:8:09: found type "Standard.Integer"
If you carefully read, you'll see that the compiler complains about the types. It expected Standard.String and got Standard.Integer.
In fact, you used Ada.Text_io which is for text only (cf. ARM).
As you want to get an integer, you must use the integer version for IO i.e. Integer_IO.
For displaying, there are several ways but you can use Integer'Image(my_int)
to convert your integer to a string.
Then check where the variable factor is declared. In fact, you never declared it but don't even have to do so.
Finally check how you can concatenate two strings, you will be able to join the "Factor =" with the integer converted to string.
When you like to get rate from the user it is good to know what rate is.
From the case statement it looks like a rate type could be declared as -
1) type Rate_Type is 1 .. 8;
2) type Rate_Type is new Integer range 1 .. 8;
3) subtype Rate_Type is Integer range 1 .. 8;
Rate : Rate_Type;
In this case (new to Ada) option 3 would be the best option. So now Rate is an Integer in the range from (including) 1 to (including) 8.
To get Rate from the user
package Rate_IO is new Ada.Text_IO.Integer_IO (Rate_Type);
The package Rate_IO is like Ada.Integer_Text_IO but for Rate_Type instead of Integer and Rate is input from the user
Rate_IO.Get (Rate);
The advantage of Rate_IO is that if the user enters a value not in the range of Rate_Type an exception (Data_Error) is raised.
This will cause the program to stop with some message.
It is often a better choice to stop the program than to let it run with a value out of range. At least it makes the program much simpler.
So now that Rate is in range, the case statement looks like
case rate is
when 1 | 2 => factor := 2 * rate - 1;
when 3 | 5 => factor := 3 * rate + 1;
when 4 => factor := 4 * rate - 1;
when 6 | 7 | 8 => factor := 1 * rate - 2;
end case;
Below is a program with an exception handler. And uncommented is an example with a default value for rate.
with ada.text_io; use ada.text_io;
with ada.integer_text_io;
procedure program_2 is
subtype rate_t is integer range 1 .. 8;
package rate_io is new ada.text_io.integer_io (rate_t);
rate : rate_t;
factor : integer;
begin
-- Input
put ("Enter rate: ");
rate_io.get (rate); -- May raise data_error exception
-- Calculate
case rate is
when 1 | 2 => factor := 2 * rate - 1;
when 3 | 5 => factor := 3 * rate + 1;
when 6 | 7 | 8 => factor := 1 * rate - 2;
when 4 => factor := 1 * rate + 0;
end case;
-- Output
put ("factor =");
ada.integer_text_io.put (factor);
new_line;
-- Error handling
exception when data_error =>
put_line ("rate out of range");
end program_2;
-- Put begin/exception/end block around rate_io.get to
-- provide ie a default value:
--
-- begin
-- rate_io.get (rate);
-- exception when data_error =>
-- rate := rate_t'first; -- A default value
-- end;

ORA-06502: PL/SQL: numeric or value error: NULL index table key value ORA-06512: at "OJC.JC_MASTER", line 129

I'm trying to run an interface in ODI 11g. When I call the procedure I get this error :
ODI-1228: Task START_JC (Procedure) fails on the target ORACLE connection OJC.
Caused By: java.sql.SQLException: ORA-06502: PL/SQL: numeric or value error: NULL index table key value
ORA-06512: at "OJC.JC_MASTER", line 129
ORA-06512: at "OJC.JC_MASTER", line 689
ORA-06512: at line 9
the sql code
PROCEDURE string_to_aa_parameter_type (
p_string VARCHAR2,
p_out_aa_parameter_values IN OUT aa_parameter_type
)
AS
v_start INTEGER := 1;
v_pos INTEGER := 0;
v_counter INTEGER := 0;
v_temp_parameter_name VARCHAR2 (4000);
v_temp_parameter_value VARCHAR2 (4000);
BEGIN
IF p_string IS NULL
THEN
RETURN;
END IF;
-- determine first chuck of string
v_pos := INSTR (p_string, '=', v_start);
-- while there are chunks left, loop
WHILE (v_pos != 0)
LOOP
v_counter := v_counter + 1;
-- create array
IF MOD (v_counter, 2) = 1
THEN
v_temp_parameter_name :=
SUBSTR (p_string, v_start, v_pos - v_start);
v_start := v_pos + 1;
v_pos := INSTR (p_string, ';', v_start);
ELSE
v_temp_parameter_value :=
SUBSTR (p_string, v_start, v_pos - v_start);
p_out_aa_parameter_values (trim(v_temp_parameter_name)) :=
trim(v_temp_parameter_value);
v_start := v_pos + 1;
v_pos := INSTR (p_string, '=', v_start);
END IF;
END LOOP;
-- IN THE FOLLOWING LINE I GET THE ERROR
v_temp_parameter_value := SUBSTR (p_string, v_start);
p_out_aa_parameter_values (trim(v_temp_parameter_name)) :=
trim(v_temp_parameter_value);
END;
Can someone help me in figuring out that the problem is ?
You'll get that error if p_string is a not-null value which doesn't contain an equals sign at all, or with any semicolon-delimited part that starts with an equals sign. It's thrown by the line after the one you indicated (or the equivalent line inside the loop, if p_string has a final semicolon).
If there is no equals sign at all then
v_pos := INSTR (p_string, '=', v_start);
gives zero, which means you don't go through the loop at all; which means when you get to that final assignment v_temp_parameter_name has never been set.
If there is a key/value pair with no key, say p_string is 'x=y;=z' you do go into the loop, and with that example the first key/value pair is added to the array; but then v_start and v_pos end up as the same value (5 in this case, both pointing to the second =). The the next time round the loop:
v_temp_parameter_name :=
SUBSTR (p_string, v_start, v_pos - v_start);
evaluates to SUBSTR(p_string, 5, 0) (where the third argument is zero because those two variables are the same), which is always going to be an empty string, or null.
There is no actual error yet, so it evaluates v_pos again, and either gets zero or non-zero, depending on whether there is a terminating semicolon.
If it's non-zero then it goes round the loop again; if it's zero it drops out. Either way it has a last stab at getting the matching value - it doesn't matter if that is set to anything or not. When it tries to add the element to the array, though, the name is still null, and you get that error, from whichever of the two array assignments it hits.
You could do additional testing and handling inside the procedure to spot and discard null keys, but
i didn't write the procedure,i have to run it . It is supposed to be syntax correct
So you need to figure out why the Java code is passing a value which the procedure can't handle - i.e. why it is sending incomplete key/value pairs.

Getting error while creating PL SQL function

Question is :
Create a Function named 'credit_limit' which takes shipment entity id(i.e, entity_id) as input and returns the limit_status of type varchar.
Function name : credit_limit
Input Parameter : entity_id in int
Output variable : limit_status variable of type varchar
Design rules:
1. If the credit_limit of the given entity id is greater then 50000,then display the limit_status as 'Credit limit is greater than 50000'
2. If the credit_limit of the given entity id is less then 50000,then display the limit_status as 'Credit limit is less than 50000'
Note: DO NOT CHANGE the given status message in your solution.
create or replace function credit_limit (entity_id in integer)
return varchar
is
c_credit_limit NUMBER(*,2);
limit_status varchar(255);
begin
select credit_limit into c_credit_limit from shipment_entity
where id = entity_id;
return(c_credit_limit);
if c_credit_limit > 50000 then
limit_status := 'Credit limit is greater than 50000';
else
if c_credit_limit < 50000 then
limit_status := 'Credit limit is less than 50000';
end if;
return (limit_status);
end;
/
I entered the code received an error
Warning: Function created with compilation errors.
please help me out.
You get issue because of 2 reasons:
1) You can return only once from a Function. You used it multiple times.
2) END IF is missing in one of the IF-ENDIF block.
Modifed code is:
CREATE OR REPLACE FUNCTION credit_limit (entity_id IN INTEGER)
RETURN VARCHAR2
IS
c_credit_limit NUMBER (5, 2);
limit_status VARCHAR (255);
BEGIN
SELECT credit_limit
INTO c_credit_limit
FROM shipment_entity
WHERE id = entity_id;
IF c_credit_limit > 50000
THEN
limit_status := 'Credit limit is greater than 50000';
ELSE
IF c_credit_limit < 50000
THEN
limit_status := 'Credit limit is less than 50000';
END IF;
END IF;
RETURN (c_credit_limit);
END;
/

Conversion failed when converting the nvarchar value 'B' to data type int

Getting this error when ever I tried to execute the entire procedure. Below is the piece of code from the procedure.
SELECT
DISTINCT SUBSTRING (a.GL06001,19,10) as ProjectNo,
--PR01040 UD_10,
SUBSTRING (a.GL06001,1,8) as AccountNo,
a.GL06002 as TransNo,
a.GL06004 as TransAmount,
a.GL06003 as TransDate,
a.GL06005 as TransDesc,
'GL' as SourceType,
' ' as ResourceCode,
' ' as TransLine,
0 as CostPR,
'000000' as PRTransNo,
a.GL06027 as SubprojNo,
a.GL06028 as ActiLineNo,
a.GL06012 as TransType,
a.GL06016 as Counter
from ScalaMX.dbo.GL06PA17 a where a.GL06003 between '2017-02-21 00:00:00.000' and '2017-03-01 00:00:00.000'
There are actually 18000+ rows and 15 columns. Any hint on how to track which column has B value?
I downloaded the result in Excel and ctrl+f 'B' But still no clue and I couldn't find it.
convert into stored procedure, see below sample
declare
n integer;
m integer;
begin
for i in ( select primarykeycolumn, a,b from table )
loop
begin
n := i.a;
m := i.b;
exception
when others then
dbms_output.put_line(i.primarykeycolumn);
end
end loop;
end;
When conversion error happens it will catch the exception hence find the primary key.

Bulding a fix length string with values passed using the length/position in pl/sql

I am writing a function which would build a fix a length empty string with value in a fix length string. for e.g.
I have a string of length 1000. When I pass string 'ABC' of length 5 with position 50, the function puts 'ABC' at 50th position of that fixed length string and pads 2 char with ' '.
I have managed to write it using regexp_replace. However I need it which doesnt use regexp_replace as it seems very slow in processing.
This function will be called in batch processing to build message string to be passed to other interface.
create or replace function insert_string(i_value varchar2, i_length number, i_position number) return varchar2
is
fix_string varchar2(1000) := ' ';
begin
fix_string := rpad(fix_string,1000,' ');
fix_string := regexp_replace(fix_string,'.{'||i_length ||'}',rpad(i_value,i_length,' '),i_position,1);
return fix_string;
end;
Something like this:
CREATE OR REPLACE FUNCTION insert_string(i_value VARCHAR2, i_length NUMBER, i_position NUMBER) RETURN VARCHAR2 IS
BEGIN
RETURN RPAD(LPAD(i_value, i_position + LENGTH(i_value) - 1), i_length);
END;
I dont know if this is what youve been trying to do/say but in case it is, ive added another parameter which will contain the source string. Without the string inside the function, its hard to manipulate values.
CREATE OR REPLACE FUNCTION INSERT_STRING(source_string VARCHAR2,
input_string VARCHAR2,
start_position NUMBER,
input_len NUMBER)
RETURN VARCHAR2 AS
TYPE char_arr IS TABLE OF CHAR(1) INDEX BY pls_integer;
TYPE char_arr2 IS TABLE OF CHAR(1);
source_array char_arr2:= char_arr2();
input_array char_arr;
X NUMBER:=1;
new_string VARCHAR2(2000);
BEGIN
FOR i IN 1..LENGTH(source_string) -- converts the source string to array
LOOP
source_array.extend;
source_array(i) := substr( source_string, i, 1 );
END LOOP;
-------------------------------------------------------------------
FOR j IN 1 .. input_len -- converts the input string to array with size input_len
LOOP
input_array(j) := substr( input_string, j, 1 );
END LOOP;
-------------------------------------------------------------------
--dbms_output.put_line(input_array(1));
FOR k IN 1..LENGTH(source_string) -- loop to insert the input_string to the source string
LOOP
IF k >= start_position THEN
source_array.extend;
source_array(k) := input_array(X) ;
x := x+1;
IF x > input_array.count THEN
exit;
end if;
END IF;
END LOOP;
FOR m IN 1 .. LENGTH(source_string) --loop to convert array back to string
LOOP
IF source_array(m) is null THEN
source_array(m) := ' ';
END IF;
new_string := new_string||source_array(m);
END LOOP;
RETURN new_string;
END;
Sample:
select insert_string('**********', 'ABC', 3, 5) from dual;
Output:
INSERT_STRING('**********','ABC',3,5)
**ABC ***
take note.
Source string should not be empty.
the size of the source string should be greater than the size of the input_string else the excess character from the input will not be inserted in the source string

Resources