Oracle : how to display second or third letter in each word of sentence as CAPITAL letter in Oracle - oracle

how to display second or third letter in each word of sentence as CAPITAL letter in Oracle.
Testdata:
hyderabad
Output:
hYderabad or hyDerabad

To make 2nd character to upper case
select SUBSTR(test_data,1,1)||INITCAP(SUBSTR(test_data,2)) from test_table;
To make the 3rd character to upper case, increment the last argument of both SUBSTR with 1.
Example
select SUBSTR(test_data,1,2)||INITCAP(SUBSTR(test_data,3)) from test_table;

Use this for 2nd digit as upper case.
WITH TBL(TESTDATA) AS
( SELECT 'hyderabad' FROM DUAL UNION
SELECT 'pune' FROM DUAL UNION
SELECT '223jjjj22' FROM DUAL
)
SELECT substr(testdata,1,1)||upper(substr(testdata,2,1))
||substr(testdata,3,length(testdata)-2)
as output
FROM TBL
Output
223jjjj22
hYderabad
pUne
Here I fetched first character,upper case of second character and rest of characters separately. Then I concatenated them.
You can use similar approach for 3rd character if you want.

Related

Correct EMAIL Oracle

I have a table with an email field this field can only have the following characters:
'abcdefghijklmnopqrstuvwxyz0123456789. # _- +'
How can you check the email field to know if I have any different characters from the ones I mentioned ('abcdefghijklmnopqrstuvwxyz0123456789. # _- +')?
This sounds like a perfect job for a regular expression - just check whether the E-Mail contains any characters that are not in your list. You can use regexp_like for this:
regexp_like(e_mail, '[^-a-z0-9.#_ +]')
(I've replaced a...z and 0..9 with the respective ranges - shorter and more readable. Note that the hyphen '-' has to be the first character after the initial caret '^' to indicate that it is a literal hyphen and not part of a character range).
Simple test case:
with v_data(e_mail) as (
select 'xyz#abc.com' from dual union all
select 'xyz(#def.com' from dual union all
select 'ab123-def#gmail.com' from dual
)
select
e_mail,
(case
when regexp_like(e_mail, '[^-a-z0-9.#_ +]') then 'NO'
else 'YES'
end) as is_valid_email
from v_data
However, a valid E-Mail adresse can contain tons of additional characters - uppercase letters for example.

FInd if the fifth position is a letter and not a number using ORACLE

How can I find if the fifth position is a letter and thus not a number using Oracle ?
My last try was using the following statement:
REGEXP_LIKE (table_column, '([abcdefghijklmnopqrstuvxyz])');
Perhaps you'd rather check whether 5th position contains a number (which means that it is not something else), i.e. do the opposite of what you're doing now.
Why? Because a "letter" isn't only ASCII; have a look at the 4th row in my example - it contains Croatian characters and these aren't between [a-z] (nor [A-Z]).
SQL> with test (col) as
2 (select 'abc_3def' from dual union all
3 select 'A435D887' from dual union all
4 select '!#$%&/()' from dual union all
5 select 'ASDĐŠŽĆČ' from dual
6 )
7 select col,
8 case when regexp_like(substr(col, 5, 1), '\d+') then 'number'
9 else 'not a number'
10 end result
11 from test;
COL RESULT
------------- ------------
abc_3def number
A435D887 not a number
!#$%&/() not a number
ASDĐŠŽĆČ not a number
SQL>
Anchor to the start of the string else you may get unexpected results. This works, but remove the caret (start of string anchor) and it returns 'TRUE'! Note it uses the case-insensitive flag of 'i'.
select 'TRUE'
from dual
where regexp_like('abcd4fg', '^.{4}[A-Z]', 'i');
Yet another way to do it:
regexp_like(table_column, '^....[[:alpha:]]')
Using the character class [[:alpha:]] will pick up all letters upper case, lower case, accented and etc. but will ignore numbers, punctuation and white space characters.
If what you care about is that the character is not a number, then use
not regexp_like(table_column, '^....[[:digit:]]')
or
not regexp_like(table_column, '^....\d')
Try:
REGEXP_LIKE (table_column, '^....[a-z]')
Or:
SUBSTR (table_column, 5, 1 ) BETWEEN 'a' AND 'z'

oracle regexp_replace to remove commas between Quote

Please can anybody help me out please. Have been trying for days to get a regexp_replace to remove commas between quotes irrespective of the commas position.
Example
cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car
Expected Answer
cold, gold, "Block 12C Jones Avenue Broad Street London", car
thanks in advance
You could extract the contents within double quotes(REGEXP_SUBSTR), replace the commas, and stuff it back to the old string using replace.
select REPLACE (whole_str,quoted_str,REPLACE (quoted_str,',')) FROM
(
select
whole_str,
REGEXP_SUBSTR( whole_str, '^[^"]*("[^"]+")',1,1,NULL,1) quoted_str
FROM yourtable
);
DEMO
Note that this could also be done using INSTR,SUBSTR which could be more efficient, but hard to read.
You can use regexp_replace to get the desired output :
with t( id , val ) as(
select 1,'cold, gold, "Block 12C, Jones Avenue, Broad Street, London", car' from dual union
select 2,'"Block 12C, Jones Avenue, Broad Street, London", car, cold, gold' from dual )
select id, val value
from t
model dimension by( id ) measures( val )
rules iterate(100)( val[any] = regexp_replace(val[cv()],',(([^"]*"){2})*([^"]*"[^"]*)$',' \1\3') );
d E m O
I doubt that there is a single regular expression function that will achieve the desired result. The "obvious" line of attack is to chop the input string into pieces and delete commas from each double-quoted substring as needed. (Unless each string has at most ONE double-quoted substring, in which case the problem has easier answers - but judging from the sample input string, it is possible that the same needs to be done for input strings with an arbitrary number of double-quoted substrings.)
Here is a solution using a recursive WITH clause - so it requires Oracle 11.2 or higher. (For earlier versions, a solution with a CONNECT BY hierarchical query can be used instead.) I wrote it with regular expressions, as requested; if speed becomes an issue, it can be re-written with standard INSTR, SUBSTR and REPLACE functions.
In the first factored subquery (subquery in the WITH clause) I created a few more inputs, to test whether the solution returns the correct result in different situations.
with
inputs ( str ) as (
select 'cold, gold, "Block 12C, Jones Ave., London", car' from dual union all
select '"One, two, three","Four, five six,",' from dual union all
select 'No, double-quotes, in this, string' from dual union all
select 'No commas in "double quotes" here' from dual
),
r ( str, init, quoted, fin ) as (
select str, null, null, str
from inputs
union all
select str,
init || replace(quoted, ',') || regexp_substr(fin, '[^"]*'),
regexp_substr(fin, '"[^"]*"'),
regexp_substr(fin, '([^"]*"){2}(.*)', 1, 1, null, 2)
from r
where quoted is not null or fin is not null
)
select str, init as new_str
from r
where quoted is null and fin is null
;
STR NEW_STR
--------------------------------------------- -------------------------------------------
No, double-quotes, in this, string No, double-quotes, in this, string
cold, gold, "Block 12C, Jay Ave, London", car cold, gold, "Block 12C Jay Ave London", car
No commas in "double quotes" here No commas in "double quotes" here
"One, two, three","Four, five six,", "One two three","Four five six",

Oracle change any string to a number

I'm having this problem we have this database witch IDS are stored in varchar2 type this ids contains Letters.
Is there any solution to convert a string to a number no matter what the value if this string.
for example there is : SELCT ASCII('t') FROM DUAL; result : 116.
but ASCII accept only one CHAR Hope you get the idea. sorry for my english
use oracle translate method to replace A-Z or a-z characters with numbers.
then use to_number to get number from it.
select translate('A1B2C3', 'ABC', '456') from dual; --result '415263'
select to_number(translate('A1B2C3', 'ABC', '456')) from dual; --result 415263
translate function documentation
The Oracle/PLSQL TRANSLATE function replaces a sequence of characters in a string with another set of characters. However, it replaces a single character at a time.
For example, it will replace the 1st character in the string_to_replace with the 1st character in the replacement_string. Then it will replace the 2nd character in the string_to_replace with the 2nd character in the replacement_string, and so on.
EDIT: After discussing further with the OP, it turns out he needed a function (in the mathematical sense) from short strings to integers. Such a function is ORA_HASH. The OP decided that ORA_HASH is likely what is needed for his project.
https://docs.oracle.com/cd/B28359_01/server.111/b28286/functions112.htm#SQLRF06313
The solution below is kept for historical perspective.
You could use the analytic function DENSE_RANK to assign numbers to strings.
For example:
with
employees ( id, first_name, last_name ) as (
select 'ABC', 'Jane', 'Smith' from dual union all
select 'ABD', 'Jane', 'Dryer' from dual union all
select 'XYZ', 'Mike', 'Lopez' from dual
)
-- End of simulated inputs (for testing purposes only).
-- Solution (SQL query) begins below this line.
select id, dense_rank() over (order by id) as num_id, first_name, last_name
from employees
;
ID NUM_ID FIRST_NAME LAST_NAME
--- ------ ---------- ---------
ABC 1 Jane Smith
ABD 2 Jane Dryer
XYZ 3 Mike Lopez

Retrieving first X words from a string in Oracle Select

I need to select the first X words in a string, where x can be any number from 0-100. Is there an easy way to do this? I found the following example to select the first 2 words from a string:
select regexp_replace('Hello world this is a test', '(\w+ \w+).*$','\1') as first_two
from dual
How would I select the first X words from a string where X can be a number from 0-100?
Selecting the first four words:
select
regexp_replace(
'Hello world this is a test etc',
'(((\w+)\s){4}).*', -- Change 4 to wanted number of words here!
'\1'
)
from dual;
Edit
The above solution only works if the words are seperated by exactly one white space character. If the words are seperated by one or more white space characters, the \s must be extended to \s+:
select
regexp_replace(
'Hello world this is a test etc',
'(((\w+)\s+){4}).*', -- Change 4 to wanted number of words here!
'\1'
)
from dual;
This method takes the result of extracting the number of words you want, then reduces multiple spaces to one:
select trim(regexp_replace(regexp_substr('Hello world this is a test etc', '(([^ ]*)( |$)*){3}'), ' +', ' '))
from dual;
EDIT: This is getting ugly, but wrapped a TRIM() around it to get rid of the trailing space (the one after the last word selected).
this would do it, but it may be a bit inelegant, replace "2" with the number of words to find
select substr('this is a number of words',1,instr('this is a number of words',' ',1,2))
from dual
does assume words always end with a space

Resources