Read a string and display the vowels and the consonants in it - oracle

I have as an assignment to read a string and to display the string of vowels and the string of consonants that are in that string. For example, if i have the string: aaceb, the string of vowels would be: aae and the string of consonants would be: cb. I have tried something on my own, but i have some errors (error starting in line 3 in command) and i can't figure it out why. Many thanks in advance :D
set serveroutput on
accept p_sir prompt "Sir=";
declare
v varchar2(20):=&p_sir;
vocale varchar2(20);
consoane varchar2(20);
c varchar2(1);
begin
for i in 1..length(v) loop
c:=substr(v,i,1);
case
when c='a' then vocale:=vocale||c;
when c='e' then vocale:=vocale||c;
when c='i' then vocale:=vocale||c;
when c='o' then vocale:=vocale||c;
when c='u' then vocale:=vocale||c;
else consoane:=consoane||c;
end case;
--dbms_output.put_line(c);
end loop;
dbms_output.put_line('vocale: ' ||vocale||' consoane:'||consoane);
end;
/

Proof of concept:
SQL> begin
2 dbms_output.put_line(translate('mathguy', 'zAEIOUaeiou', 'z'));
3 end;
4 /
mthgy
PL/SQL procedure successfully completed.

Use a regular expression to:
remove the non-vowels [^aeiou] to be left with only the vowels.
remove the vowels [aeiou] and non-alphabetic characters [^a-z] to be left with only the consonants.
Like this:
DECLARE
v_text VARCHAR2(200) := 'Your text string';
BEGIN
DBMS_OUTPUT.PUT_LINE(
'Vowels: ' || REGEX_REPLACE( v_text, '[^aeiou]', NULL, 1, 0, 'i' )
);
DBMS_OUTPUT.PUT_LINE(
'Consonants: ' || REGEX_REPLACE( v_text, '[aeiou]|[^a-z]', NULL, 1, 0, 'i' )
);
END;
/

Related

How we can get the value from string: 1;BWQTY;4|2;NGRID;34664 and store into a variable if any specific SUBSTRING found?

I have a table name as event_creation_template which having column as TEXT ,which contains value like below :
1;BWQTY;4|2;NGRID;34664
1;DTYPE;Amount|2;LOYAL;R
How we can get the value from string:
1;BWQTY;4|2;NGRID;34664
If string is having BWQTY then store 4 into variable again search for the NGRID ,if string contains NGRID , we need in 34664 into different variable.
using Oracle PL/SQL.
considering the string like 'BWQTY' will always lie between two non-aphanumeric characters and the corresponding values like 4 lies between either non-alphanumeric character or appears at the end like in the two examples above you can use below code
CREATE OR REPLACE PR_PREP
IS
V_VAR1 VARCHAR2(100);
V_-VAR2 VARCHAR2(100);
V_SEARCH_VAL1 VARCHAR2(100) := 'BWQTY';
V_SEARCH_VAL2 VARCHAR2(100) := 'NGRID';
CURSOR C1
IS
SELECT TEXT FROM EVENT_CREATION_TEMPLATE;
BEGIN
FOR REC IN C1
LOOP
IF INSTR(REC.TEXT,V_SEARCH_VAL1) > 0 THEN
SELECT NVL(SUBSTR(SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL1)+LENGTH(V_SEARCH_VAL1)+1), 1, REGEXP_INSTR( SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL1)+LENGTH(V_SEARCH_VAL1)+1), '[^0-9a-zA-Z]',1)-1), SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL1)+LENGTH(V_SEARCH_VAL1)+1))
INTO V_VAR1
FROM DUAL ;
END IF;
IF INSTR(REC.TEXT,V_SEARCH_VAL2) > 0 THEN
SELECT NVL(SUBSTR(SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL2)+LENGTH(V_SEARCH_VAL2)+1), 1, REGEXP_INSTR( SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL2)+LENGTH(V_SEARCH_VAL2)+1), '[^0-9a-zA-Z]',1)-1), SUBSTR(REC.TEXT,INSTR(REC.TEXT,V_SEARCH_VAL2)+LENGTH(V_SEARCH_VAL2)+1))
INTO V_VAR2
FROM DUAL ;
END IF;
-- DO FURTHER WORK
END LOOP;
END;
You can use regular expressions
for BWQTY:
select str,
SUBSTR(REGEXP_SUBSTR(str, '([BWQTY]{5})([;])([0-9]+)'),
INSTR(REGEXP_SUBSTR(str, '([BWQTY]{5})([;])([0-9]+)'), ';') + 1 ,
LENGTH(REGEXP_SUBSTR(str, '([BWQTY]{5})([;])([0-9]+)')) - INSTR(REGEXP_SUBSTR(str, '([BWQTY]{5})([;])([0-9]+)'), ';')) AS VALUE
from test
for NGRID:
select str,
SUBSTR(REGEXP_SUBSTR(str, '([NGRID]{5})([;])([0-9]+)'),
INSTR(REGEXP_SUBSTR(str, '([NGRID]{5})([;])([0-9]+)'), ';') + 1 ,
LENGTH(REGEXP_SUBSTR(str, '([NGRID]{5})([;])([0-9]+)')) - INSTR(REGEXP_SUBSTR(str, '([NGRID]{5})([;])([0-9]+)'), ';')) AS VALUE
from test
Where str is your input string...

How to built a dynamic string PLSQL

I have 2 associative_arrays of number and I am trying to built a dynamic string for a dynamic query.
This is my for statement:
for indx_opt in 1..IDOPTarray.count loop
IF indx_opt=1 AND IDFGCFCParray.count=1 THEN
sql_stmt_2:=sql_stmt_2||' and wopt.id_ft_opt = ';
sql_stmt_2:=sql_stmt_2|| (IDOPTarray(indx_opt));
end if;
if indx_opt=1 AND IDFGCFCParray.count>1 then
sql_stmt_2:=sql_stmt_2||' and wopt.id_ft_opt in(';
sql_stmt_2:=sql_stmt_2||(IDOPTarray(indx_opt));
elsif indx_opt>=1 AND IDFGCFCParray.count>=0 then
sql_stmt_2:=sql_stmt_2||','||(IDOPTarray(indx_opt))||')';
With 2 number in IDOPTarray I get a correct result:
and wopt.id_ft_opt in(27,28)
Instead with more then 2 number in IDOPTarray I get this result:
,17228),17229),17230)
What I want to get is this:
where w.id = 303 and wopt.id_ft_opt in (17228,17229,17230)
if I have 5 numbers, I want to get this for the 'where' clause:
where w.id = 321 and wopt.id_ft_opt in (17228,17229,17230,17231,17232)
I want a dynamic output of my string.
IDFGCFCParray is the 2nd array, but is not important right now in order to get the output I want.
Does somebody can help me? thank you.
You have to close bracket only if indx_opt is equil to IDOPTarray.count.
And simple example.
declare
type list_number is table of number;
xx list_number := new list_number(1,2,3,5,7,8);
str varchar2(4000);
begin
for i in xx.first .. xx.last loop
if i = 1 then
str := ' condition in ('||xx(i);
else
str := str||','||xx(i);
end if;
if i = xx.last then
str := str||')';
end if;
end loop;
dbms_output.put_line(str);
end;
If you colleciton is sql levle type you can do this in this way
declare
xx list_number := new list_number(1,2,3,5,7,8);
str varchar2(4000);
begin
SELECT 'condition in ('||LISTAGG(column_value, ',') WITHIN GROUP (ORDER BY column_value)||')' into str from table(xx);
dbms_output.put_line(str);
end;

Oracle regexp_like word boundaries multiple words workaround

As you know Oracle POSIX implementation of regexes does not support word boundaries. One workaround is suggested here:
Oracle REGEXP_LIKE and word boundaries
However it does not work if I want to, for instance select all 4 character strings. Consider this, for example:
myvar:=regexp_substr('test test','(^|\s|\W)[\S]{4}($|\s|\W)')
This obviously selects only the first occurrence. I do not know how to do this in the Oracle world, although normally it is simply (\b)[\S]{4}(\b). The problem is that most woraround rely on some nonexistent feature, like lookaround etc.
select xmlcast(xmlquery('for $token in ora:tokenize(concat(" ",$in)," ")
where string-length($token) = $size
return $token' passing 'test test' as "in", 4 as "size" returning content) as varchar2(2000)) word from dual;
Xquery and FLWOR expresion.
concat(" ",$in) - workaround if input string is null or it has only 1 matchting word.
ora:tokenize - tokenize string by "space"
string-length($token) = $size check if token has appropriate length.
xmlcast - convert xmltype to varchar2
Easy ? Any question:)
DECLARE
str VARCHAR2(200) := 'test test';
pattern VARCHAR2(200) := '(\w+)($|\s+|\W+)';
match VARCHAR2(200);
BEGIN
FOR i IN 1 .. REGEXP_COUNT( str, pattern ) LOOP
match := REGEXP_SUBSTR( str, pattern, 1, i, NULL, 1 );
IF LENGTH( match ) = 4 THEN
DBMS_OUTPUT.PUT_LINE( match );
END IF;
END LOOP;
END;
/
or (without using REGEXP_COUNT or the 6th parameter of REGEXP_SUBSTR that was introduced in 11G):
DECLARE
str VARCHAR2(200) := 'test test';
pattern CONSTANT VARCHAR2(3) := '\w+';
match VARCHAR2(200);
i NUMBER(4,0) := 1;
BEGIN
match := REGEXP_SUBSTR( str, pattern, 1, i );
WHILE match IS NOT NULL LOOP
IF LENGTH( match ) = 4 THEN
DBMS_OUTPUT.PUT_LINE( match );
END IF;
i := i + 1;
match := REGEXP_SUBSTR( str, pattern, 1, i );
END LOOP;
END;
/
Output:
test
test
If you want to use this in SQL then you can easily translate it into a pipelined function or a function that returns a collection.

read() strings of variable length

I've got rows of two values (input from console) that look likes this:
David 89000
Peter 99500
Jim 23999
END 1
is there a way to save the string and number into a variable other than to loop-read a char when you don't know the string length?
str:=''; salary:=0; i:=1;
while str<> 'END' do
begin
str:=''; salary:=0;
read(ch);
while ch <> ' ' do
begin
str:=str+ch;
read(ch);
end;
read(salary);
array[i].name:=str;
array[i].salary:=salary;
i:=i+1;
readln;
end;
You can do it with a single call to ReadLn and then parse the input yourself:
var
TextIn: string;
Person: string;
Salary: Integer;
begin
while true do
begin
ReadLn(TextIn); // Requires user to hit Enter
if Copy(TextIn, 1, 3) <> 'END' then
begin
Person := Copy(TextIn, 1, Pos(' ', TextIn) - 1);
Salary := StrToInt(Copy(TextIn, Pos(' ', TextIn) + 1, 255);
end
else
Exit;
end;
end;
I didn't include any error checking (which should be there), because your original code doesn't have any either.
Not with standard I/O functions. Of course you can put that code in a separate procedure, or split with tstringlist.

PL/SQL - String concatenation algorithm

I'm working on a PL/SQL algorithm, with Oracle.
I currently have a procedure which have one single numeric parameter. My procedure have to create a string which contains as much '0' as the parameter value.
I am currently using a for loop to achieve this:
MY_STRING VARCHAR2(30);
FOR I IN 1..MY_PARAMETER
LOOP
MY_STRING := CONCAT(MY_STRING, '0');
END LOOP;
Is it possible to do it in a linear way ? I mean without a loop, or even with one single statement.
Any help would be appreciated !
Thanks.
You can use LPAD() to achieve this:
SELECT LPAD('0', my_parameter, '0')
FROM DUAL
Here is the link to the manual:
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions082.htm#i1371196
Demonstration of accepted answer using various input values.
set serveroutput on size 1000000 format wrapped
Declare
my_parameter Number(3);
my_string Varchar2(10);
Begin
DBMS_Output.Put_Line('Input Output');
DBMS_Output.Put_Line('===== ======');
For vLoopVar IN 0..5 Loop
my_parameter := vLoopVar;
If (vLoopVar = 5) Then
my_parameter := '';
End If;
DBMS_Output.Put(RPAD('~' || my_parameter || '~',6));
--Method 1
my_string := lpad('0',my_parameter,'0');
DBMS_Output.Put_Line('~' || my_string || '~');
End Loop;
End;
/
Output
Input Output
===== ======
~0~ ~~
~1~ ~0~
~2~ ~00~
~3~ ~000~
~4~ ~0000~
~~ ~~

Resources