Oracle Pattern matching - oracle

In Oracle I want to check whether the string has "=' sign at the end. could you please let me know how to check it. If it has '=' sign at the end of string, I need to trailing that '=' sign.
for eg,
varStr VARCHAR2(20);
varStr = 'abcdef='; --needs to trailing '=' sign

I don't think you need "pattern matching" here. Just check if the last character is the =
where substr(varstr, -1, 1) = '='
substr when called with a negative position will work from the end of the string, so substr(varstr,-1,1) extracts the last character of the given string.

Use the REGEX_EXP function. I'm putting a sql command since you didn't specify on your question.:
select *
from someTable
where regexp_like( someField, '=$' );
The pattern $ means that the precedent character should be at the end of the string.
see it here on sql fiddle: http://sqlfiddle.com/#!4/d8afd/3

It seems that substr is the way to go, at lease with my sample data of about 400K address lines this returns 1043 entries that end in 'r' in an average of 0.2 seconds.
select count(*) from addrline where substr(text, -1, 1) = 'r';
On the other hand, the following returns the same results but takes 1.1 seconds.
select count(*) from addrline where regexp_like(text, 'r$' );

Related

Sybase UDF difficulty

When I try to run the following function on Sybase ASE 15.7, it just spins indefinitely. Each component of the function seems to act as expected independently. This is simply a mechanism to strip all non-numeric characters from a string. Any and all thoughts appreciated.
create function dbo.mdsudf_just_digits(#str varchar(64))
returns varchar(64)
as
begin
while patindex('%[^0-9]%', #str) > 0
set #str = stuff(#str, patindex('%[^0-9]%', #str), 1, '')
return #str
end
-- A typical invocation would be like so:
select dbo.mdsudf_just_digits('hello123there456')
```
In Sybase (ASE) the empty string ('') actually translates into a single space:
select '.'+''+'.' -- period + empty string + period
go
---
. . -- we get a space between the periods
So in the current stuff(#str, ..., 1, '') you're actually replacing the first non-numeric with a single space. This 'new' space then matches the non-number test on the next pass through the loop at which point the space is replaced with ... another space. This is leading to an infinite loop of constantly replacing the first non-number character with a space.
You can get around this by using NULL as the last arg to the stuff() call, eg:
set #str = stuff(#str, patindex('%[^0-9]%', #str), 1, NULL)

Invalid Number In substr

I Used substring for this query
to_number(substr(skidno,instr(skidno,'/')+1,length(skidno)))
this i'll pass for ths query Skid no 'MMM-1718/000325 / 1' i got Invalid Number
If your need is to extract the part after the 2nd occurrence of "/"; the following query will suffice your need ---
select to_number(trim('/' FROM
substr('MMM-1718/000325 / 1',
instr('MMM-1718/000325 / 1', '/', 1, 2))))
from dual;
You may want to use regexp_substr. If you want to only get the number at the end of the value:
to_number(regexp_substr(skidno, '\d+$'))
You cannot convert it to number because you will get "/" in the result.
Result: '000325 / 1'.
If you only require only the number between '/' then try below :
to_number(substr(skidno ,instr(skidno ,'/')+1,
instr(skidno ,'/',1,2) -instr(skidno ,'/',1,1)-1 ))
Since you need part of the string that begins after second occurrence of '/' character and goes to the end of the string, the following solution is probably the easiest using substr/instr:
with t as
(
select 'MMM-1718/000325 / 1' mystring
from dual
)
select to_number(substr(mystring, instr(mystring, '/', 1, 2) + 1))
from t;
Note: in this case you just have to define starting position in substr function; length of the string is not needed.

Format string in Oracle

I'm building a string in oracle, where I get a number from a column and make it a 12 digit number with the LPad function, so the length of it is 12 now.
Example: LPad(nProjectNr,12,'0') and I get 000123856812 (for example).
Now I want to split this string in parts of 3 digit with a "\" as prefix, so that the result will look like this \000\123\856\812.
How can I archive this in a select statement, what function can accomplish this?
Assuming strings of 12 digits, regexp_replace could be a way:
select regexp_replace('000123856812', '(.{3})', '\\\1') from dual
The regexp matches sequences of 3 characters and adds a \ as a prefix
It is much easier to do this using TO_CHAR(number) with the proper format model. Suppose we use \ as the thousands separator.... (alas we can't start a format model with a thousands separator - not allowed in TO_CHAR - so we still need to concatenate a \ to the left):
See also edit below
select 123856812 as n,
'\' || to_char(123856812, 'FM000G000G000G000', 'nls_numeric_characters=.\') as str
from dual
;
N STR
--------- ----------------
123856812 \000\123\856\812
Without the FM format model modifier, TO_CHAR will add a leading space (placeholder for the sign, plus or minus). FM means "shortest possible string representation consistent with the model provided" - that is, in this case, no leading space.
Edit - it just crossed my mind that we can exploit TO_CHAR() even further and not need to concatenate the first \. The thousands separator, G, may not be the first character of the string, but the currency symbol, placeholder L, can!
select 123856812 as n,
to_char(123856812, 'FML000G000G000G000',
'nls_numeric_characters=.\, nls_currency=\') as str
from dual
;
SUBSTR returns a substring of a string passed as the first argument. You can specify where the substring starts and how many characters it should be.
Try
SELECT '\'||SUBSTR('000123856812', 1,3)||'\'||SUBSTR('000123856812', 4,3)||'\'||SUBSTR('000123856812', 7,3)||'\'||SUBSTR('000123856812', 10,3) FROM dual;

I want fetch substring from in oracle table between last '/' and before '.' from last in images table

I want to fetch substring from string in column between last '/' and last '.' .
Here is sample date for IMAGE_PATH column name:
sph/images/30_Fairhall_Court.jpeg
sph/images/9_Pennethorne_House.jpeg
rbkc/images/TAVISTOCK_CRESCENT.jpeg
haringey/images/399932thumb.jpg
urbanchoice/images/18190862.jpg
wandle/images/f13c10d2-2692-457d-a208-8bb9e10b27dc.png
housingmoves/images/No14_Asterid Heights_DS37620.jpg
wandle/images/f13c10d2-2692-457d-a208-8bb9e10b27dc.png
So the required output is like
30_Fairhall_Court
9_Pennethorne_House
TAVISTOCK_CRESCENT
399932thumb
18190862
f13c10d2-2692-457d-a208-8bb9e10b27dc
No14_Asterid Heights_DS37620
f13c10d2-2692-457d-a208-8bb9e10b27dc
Please suggest how to fetch. I need to update another blank column in table with this value. The table has around 10 lacks records.
One of possible solutions is to use functions substr() and instr() with negative third parameter:
select image_path,
substr(image_path,
instr(image_path, '/', -1) + 1,
instr(image_path, '.', -1)-instr(image_path, '/', -1) - 1) img
from test
SQL Fiddle
Results:
IMAGE_PATH IMG
-------------------------------------------------------- -------------------------------------
sph/images/30_Fairhall_Court.jpeg 30_Fairhall_Court
sph/images/9_Pennethorne_House.jpeg 9_Pennethorne_House
rbkc/images/TAVISTOCK_CRESCENT.jpeg TAVISTOCK_CRESCENT
haringey/images/399932thumb.jpg 399932thumb
urbanchoice/images/18190862.jpg 18190862
wandle/images/f13c10d2-2692-457d-a208-8bb9e10b27dc.png f13c10d2-2692-457d-a208-8bb9e10b27dc
housingmoves/images/No14_Asterid Heights_DS37620.jpg No14_Asterid Heights_DS37620
wandle/ima.ges/f13c10d2-2692-457d-a208-8bb9e10b27dc.png f13c10d2-2692-457d-a208-8bb9e10b27dc
This regex works with the sample data you provided:
select regexp_substr(image_path
, '(/)([a-z0-9_ \-]+)(\.)([a-z]+)$'
, 1
, 1
, 'i'
, 2)
from t23
/
We have to include all the optional parameters after pattern so we can use the subexpr parameter to select just the filename element. Find out more.
As far as the updating goes, a million row table isn't that big. Given that you have to update all the rows there's not much you can do to tune it. Just issue the UPDATE statement and let it rip.
"its not working"
Hmmm, here's a SQL Fiddle which proves it does work. You've probably introduced a typo.
"The regexp looks unnecessary complex. Why not simply"
Perhaps it is too complicated. However your simplified version doesn't produce the correct result if there's more than one dot in the IMAGE_PATH. If that's never going to happen then your solution works just fine.

Decoding with SUBSTRING and INSTRING?

I have a table which has city column having few records with state values as well-separated by comma.
There are other records without, as well. I want to take the state values for those present into a separate field called state.
How to do that? I tried the code below and it is saying "missing right parenthesis":
SELECT DECODE(ORA_CITY,
INSTR(ORA_CITY,',') > 0,
SUBSTR(ORA_CITY, INSTR(ORA_CITY, ','), LENGTH(ORA_CITY) ) ,
NULL) AS STATE
from ADDRESS
I don't know if you still need it but use CASE:
SELECT CASE
WHEN INSTR(ORA_CITY, '5') > 0 THEN
SUBSTR(ORA_CITY, INSTR(ORA_CITY, '5'), LENGTH(ORA_CITY))
ELSE
NULL
END STATE
FROM ADDRESS
Clearly you have not understood decode syntax.
Try the following:
SELECT DECODE(INSTR(ORA_CITY,','),
0,
NULL,
SUBSTR(ORA_CITY, INSTR(ORA_CITY, ','), LENGTH(ORA_CITY) )) AS STATE
FROM ADDRESS
The correct syntax is:
DECODE( expression , search , result [, search , result]... [,
default] ), where
expression is the value to compare.
search is the value that is compared against expression.
result is the value returned, if expression is equal to search.
default is optional. If no matches are found, the DECODE function will
return default. If default is omitted, then the DECODE function will
return null (if no matches are found).
Examples here and here
SELECT REGEX_REPLACE(ORA_CITY, '.*, *', '') AS STATE
FROM ADDRESS
WHERE ORA_CITY LIKE '%,%'
This uses regular expression to replace all upto the comma, and then maybe spaces with nothing. A WHERE included.

Resources