Oracle change any string to a number - oracle

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

Related

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",

Split a name field in Oracle into First and Last Name

I've got a table with names in it, which looks like this:
Emp_ID Emp_Name
0001 Jack Skelly
0002 Susan Ryan
I need to produce something that looks like this:
Emp_ID Emp_F_Name Emp_L_Name
0001 Jack Skelly
0002 Susan Ryan
I've come up with this to split the name:
SubStr(d.Name, 0, InStr(d.Name, ' ')-1) as FName,
SubStr(d.Name, InStr(d.Name, ' ')+1) as LName
I've seen people suggest INSTR, I've seen people suggest regexp_instr and I've seen them suggest regexp_substr. I'm still new to Oracle and I don't really understand either, or which (if either) of them is more efficient for the split I need to do. Can someone tell me the best way to go about splitting this field? Is the method I've used the best/most efficient for what I want to do?
substr and instr are almost always faster/more efficient than regular expression functions.
INSTR is used to find the position of the space in the input string. SUBSTR is used to extract a substring from the input string. Search (google) the Oracle documentation for these functions - you will find detailed explanations and examples.
The bigger issue you will have with your problem is the business requirement - what do you do with names like "John Clayton Stuart", "Ali Abu Ahmad", or single-word like "Belphegor"?
The query below shows how easily you can solve the problem if all the names have the format "Firstname Lastname".
with
input_table ( emp_id, emp_name ) as (
select '0001', 'Jack Skelly' from dual union all
select '0002', 'Susan Ryan' from dual
)
-- End of simulated input data (not part of the solution).
-- SQL query begins BELOW THIS LINE.
select emp_id, emp_name,
substr(emp_name, 1, instr(emp_name, ' ') - 1) as first_name,
substr(emp_name, instr(emp_name, ' ') + 1) as last_name
from input_table
;
EMP_ID EMP_NAME FIRST_NAME LAST_NAME
---- ----------- ----------- -----------
0001 Jack Skelly Jack Skelly
0002 Susan Ryan Susan Ryan

Applying where condition on Casted number coulmn in ORACLE from a inner query result

For Sample purpose lets create a table with below schema and fill some sample values
CREATE TABLE games(ID INT ,Name VARCHAR(20));
INSERT INTO games(ID,Name) VALUES (2008,'Beijing');
INSERT INTO games(ID,Name) VALUES (2012,'London');
INSERT INTO games(ID,Name) VALUES (2012,12);
INSERT INTO games(ID,Name) VALUES (2012,654);
Output:
ID NAME
2008 Beijing
2012 London
2012 12
2012 654
In the above table we have both number and string data in the name column lets write a query that uses the REGX to filter only the numerical rows
SELECT TO_NUMBER(Name)as Trimmed FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '')
Output:
TRIMMED
12
654
Now here is the problem if write a where clause of getting values greater than 12 from the above result it throws invalid number.
Select * from (SELECT TO_NUMBER(Name)as Trimmed FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '')) T1 where T1.Trimmed >12 ;
I found this is how the oracle query planning works but is there any other way i can achieve this
This will work:
Select * from
(SELECT Name as Trimmed
FROM games where REGEXP_LIKE(Name, '(?<=\s|^)\d+(?=\s|$)', '')) T1
where to_number(T1.Trimmed) >12 ;
Unfortunately you need a subquery. It can't be done with one where.
This can be done in a single query:
with
inputs as (
select 2008 as id, 'Beijing' as name from dual union all
select 2012 , 'London' from dual union all
select 2012 , '12' from dual union all
select 2012 , '654' from dual
)
select id, name
from inputs
where translate(name, 'a0123456789', 'a') is null
and to_number(regexp_replace(name, '[^[:digit:]]', '')) > 12
;
ID NAME
---------- -------
2012 654
1 row selected.
regexp_replace removes all the characters except digits, so the test can be done regardless of what the name is. If there are no digits in the name, the result is NULL, which can be converted to number (it is still null).
The translate solution for testing for "all-digits" is more efficient than using regexp_like. The odd-looking 'a' in translate is needed due to an oddity in the translate function itself (see the documentation). This test is not needed if all the names are either "all letters" or "all digits" (if "all letters", the second test with regexp_replace would suffice); but the first test is needed if names like "Sydney 2000" are possible in the name column.

Oracle : how to display second or third letter in each word of sentence as CAPITAL letter in 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.

Sorting results on Oracle as ASCII

I'm doing a query that returns a VARCHAR2 and some other fields. I'm ordering my results by this VARCHAR2 and having some problems related to the linguistic sort, as I discovered on Oracle documentation. For example:
SELECT id, my_varchar2 from my_table ORDER BY MY_VARCHAR2;
Will return:
ID MY_VARCHAR2
------ -----------
3648 A
3649 B
6504 C
7317 D
3647 0
I need it to return the string "0" as the first element on this sequence, as it would be comparing ASCII values. The string can have more than one character so I can't use the ascii function as it ignores any characters except for the first one.
What's the best way to do this?
For that case, you should be able to just order by the BINARY value of your characters;
SELECT id, my_varchar2
FROM my_table
ORDER BY NLSSORT(MY_VARCHAR2, 'NLS_SORT = BINARY')
SQLFiddle here.

Resources