I'm looking at someone else's code which I do not have the option of running and can't figure out what the following REGEXP_LIKE is trying to match. Any help would be appreciated.
REGEXP_LIKE('field_name', '^(ABC:)?Z[DEF]')
What I think is happening is as follows but I think I am wrong:
Try to match any field that:
begins with ABC:
and ends D, E or F
I understand that the ^ matches the beginning of a string and that the () brackets group the expressions so is therefore grouping ABC:
However the ?Z is what is confusing me.
Any help would be appreciated, I can't seem to get my head around this no matter how many articles I read.
Try playing with some different strings:
with example as (select 'BC:ZDEF' as x from dual
union select 'ABC:D' from dual
union select 'ABC:ZE' from dual
union select 'ZE' from dual
union select 'ZF' from dual)
select x
from example
where REGEXP_like(x, '^(ABC:)?Z[DEF]');
Output:
x
ABC:ZE
ZE
ZF
So what's going on? You're right about ^ meaning the beginning of a line. The ? operator means the thing that comes before this is optional - it should occur 1 or 0 times. In this case, that's (ABC:), so that part of the string is optional.
Then we have a Z, which is mandatory, followed by a bracket expression, which means any single character listed between the brackets - so either D, E, or F.
So the expression means "a line starting with Z followed by D, E, or F, optionally with an "ABC:" at the beginning".
Related
While reading upon the difference between decode function and CASE WHEN statement, I got confused while understanding that if both give the same result for a simple equation like the following:
DECODE(col1, 'ABC', 'DEF', 'OTHERS' ) AS COL2
CASE WHEN COL1 = 'ABC' THEN 'DEF'
ELSE 'OTHERS'
END AS COL2
Then what is the difference between the functionality of a function and a statement?
p.s. I am aware Case is capable of taking more complex equations... my question here is more about understanding difference between function and statement.
In SQL, there is no such thing as a "CASE statement". Your example is a CASE expression. (CASE statements do exist in PL/SQL.)
The documentation states "An expression is a combination of one or more values, operators, and SQL functions that evaluates to a value." So a SQL function is not different from an expression, it is a specific type of expression.
Note that DECODE and CASE behave differently when comparing NULL values: DECODE considers two NULLs to be "the same", which is an exception to the rule that comparing a NULL to anything has an "unknown" result.
with data(a, b) as (
select 1,1 from dual union all
select 1,null from dual union all
select null,1 from dual union all
select null, null from dual
)
select a, b,
decode(a,b,'same','different') decode_result,
case when a = b then 'same' else 'different' end case_result
from data;
A B DECODE_RESULT CASE_RESULT
------ ------ ------------- -----------
1 1 same same
1 (null) different different
(null) 1 different different
(null) (null) same different
I'm pretty much sure that CASE didn't exist in pre-9i Oracle database versions so you had to use DECODE.
No difference, they will both do the same job, but CASE is simpler to maintain. DECODE can grow to a real monster when complex things have to be done, with nested DECODEs so you probably know what you're doing while typing that statement, but a month later you're in deep trouble as you don't know what belongs to what, which closing bracket is closing which open bracket, ... real nightmare.
But, for simple things, it is quite OK. Saves some typing.
A function is simply some functionality capsuled. With a function you can call a functionality from anywhere without spelling it out explicitely. There are predefined functions like DECODE() or you can define functions yourself.
A statement is something like select 1 from dual and may contain functions (select decode(col1,'1','yes','no') from mytable).
The statement is (as long as you aren't in a block, which itself may contain several statements) an order you send to the DB, a function is kindof an instruction what to do with the given arguments.
This question already has answers here:
Can't we use [specifier] with like operator with Oracle?
(1 answer)
Query the list of CITY names starting with vowels (i.e., a, e, i, o, or u) from STATION
(18 answers)
Closed 3 years ago.
I am trying to find all the name that starts with either A,B or C in Oracle DB and I wrote this syntax:
SELECT NUME FROM JUCATORI
WHERE NUME LIKE '[ABC]%';
but it doesn't not give me any name (neither error), even though I am sure I have in my DB names that starts with either A,B or C.
LIKE doesn't work with character sets. (I think T-SQL extended LIKE to deal with such expressions, but Oracle's SQL doesn't.) You don't get an error, because LIKE '[ABC]%' looks for strings starting with an opening bracket, followed by an A, then a B, then a C, then a closing bracket
So either use OR:
SELECT nume FROM jucatori WHERE nume LIKE 'A%' OR nume LIKE 'B%' OR nume LIKE 'C%';
Or a regular expression:
SELECT nume FROM jucatori WHERE REGEXP_LIKE(nume, '^[ABC]');
One option is
where substr(nume, 1, 1) in ('A', 'B', 'C')
You're confusing regular expressions with 'like' conditions.
Like checks for exactly the string you pass to it, with the only three exceptions being:
1. % - any number of any characters
2. _ - any single character
3. ESCAPE clause that lets you define escape character
so you can use % as 'I'm looking for percent sign'
[ABC] meaning 'either A, B or C' is a regular expression syntax.
You may want to use regexp_like instead, or for such simple query just 'OR' several likes:
with examples as (
select 'Adam' ex from dual union all
select 'Dorothy' ex from dual union all
select '[ABC]something' ex from dual union all
select '[ABC]' from dual
)
select e.ex,
case when e.ex like '[ABC]%' then 'MATCHES' else null end as matches_like,
case when regexp_like(e.ex, '^[ABC].?') then 'MATCHES' else null end as matches_regexp_like,
case when e.ex like 'A%' or e.ex like 'B%' or e.ex like 'C%' then 'MATCHES' else null end as matches_complex_like
from examples e
I have below query which gives me output like -$97.90 or $11.00
Select TRIM(to_char(pen_amt,'$999,999,999,999,999.99')) as PenAmount
from transact;
Now, if the value starts with -, I want to remove - and encapsulate the same as ($97.90). How can I do this?
Also using the PR format model element, which surrounds positive (and zero) values with single spaces and negative numbers with angled brackets: You can follow that up with the TRANSLATE function if you really need the format you requested. (Notice that if I use TRANSLATE, I don't need to use TRIM, or the format model modifier FM in TO_CHAR, which would do the same thing; I can simply remove the spaces with TRANSLATE.)
with
test_data (amount) as (
select 320.88 from dual union all
select -309 from dual
)
select amount,
to_char(amount, '$999,999,999.99pr') as pr_formatted_amount,
translate(to_char(amount, '$999,999,999.99pr'), '<> ', '()')
as my_formatted_amount
from test_data
;
AMOUNT PR_FORMATTED_AMOUNT MY_FORMATTED_AMOUNT
---------- ------------------- -------------------
320.88 $320.88 $320.88
-309 <$309.00> ($309.00)
If you can use <> brackets then PR will do the trick.
Select TRIM(to_char(pen_amt,'$999,999,999,999,999.99PR')) as PenAmount from transact;
Use a CASE statement to check if the value starts with -:
Select
case when TRIM(to_char(pen_amt,'$999,999,999,999,999.99')) like '-%'
then '(' || substr(TRIM(to_char(pen_amt,'$999,999,999,999,999.99')), 2) || ')'
else TRIM(to_char(pen_amt,'$999,999,999,999,999.99'))
end as PenAmount
from transact;
Or by directly checking if pen_amt is negative:
Select
case when pen_amt < 0
then '(' || TRIM(to_char(abs(pen_amt),'$999,999,999,999,999.99')) || ')'
else TRIM(to_char(pen_amt,'$999,999,999,999,999.99'))
end as PenAmount
from transact;
Use a combination of PR in the mask along with TRANSLATE to convert angle brackets to parentheses.
Select translate(to_char(-12345.6789,'FM$999,999,999,999,999.99PR'),'<>','()') as PenAmount from dual;
Select translate(to_char(23456.789,'FM$999,999,999,999,999.99PR'),'<>','()') as PenAmount from dual;
($12,345.68)
$23,456.79
The PR mask puts angle brackets for negative numbers.
The FM mask tells Oracle to show the minimal text (i.e. TRIM it).
i have a string 'MCDONALD_YYYYMMDD.TXT' i need to use regular expressions and append the '**' after the letter 'D' in the string given . (i.e In the string at postion 9 i need to append '*' based on a column value 'star_len'
if the star_len = 2 the o/p = ''MCDONALD??_YYYYMMDD.TXT'
if the star_len = 1 the o/p = ''MCDONALD?_YYYYMMDD.TXT'
with
inputs ( filename, position, symbol, len ) as (
select 'MCDONALD_20170812.TXT', 9, '*', 2 from dual
)
-- End of simulated inputs (for testing purposes only, not part of the solution).
-- SQL query begins BELOW THIS LINE.
select substr(filename, 1, position - 1) || rpad(symbol, len, symbol)
|| substr(filename, position) as new_str
from inputs
;
NEW_STR
-----------------------
MCDONALD**_20170812.TXT
select regexp_replace('MCDONALD_YYYYMMDD.TXT','MCDONALD','MCDONALD' ||
decode(star_len,1,'*',2,'**'))
from dual
This is how you could do it. I don't think you need it as a regular expression though if it is always going to be "MCDONALD".
EDIT: If you need to be providing the position in the string as well, I think a regular old substring should work.
select substr('MCDONALD_YYYYMMDD.TXT',1,position-1) ||
decode(star_len,1,'*',2,'**') || substr('MCDONALD_YYYYMMDD.TXT',position)
from dual
Where position and star_len are both columns in some table you provide(instead of dual).
EDIT2: Just to be more clear, here is another example using a with clause so that it runs without adding a table in.
with testing as
(select 'MCDONALD_YYYYMMDD.TXT' filename,
9 positionnum,
2 star_len
from dual)
select substr(filename,1,positionnum-1) ||
decode(star_len,1,'*',2,'**') ||
substr(filename,positionnum)
from testing
For the fun of it, here's a regex_replace solution. I went with a star since that what your variable was called even though your example used a question mark. The regex captures the filename string in 2 parts, the first being from the start up to 1 character before the position value, the second the rest of the string. The replace puts the captured parts back together with the stars in between.
with tbl(filename, position, star_len ) as (
select 'MCDONALD_20170812.TXT', 9, 2 from dual
)
select regexp_replace(filename,
'^(.{'||(position-1)||'})(.*)$', '\1'||rpad('*', star_len, '*')||'\2') as fixed
from tbl;
Select /*+USE_HASH( a b ) */ to_char(date, 'MM/DD/YYYY HH24:MI:SS') as LABEL,
ltrim(rtrim(substr(oled, 9, 16))) as VALUE,
from rrfh a, rrf b,
where ltrim(rtrim(substr(oled, 1, 9))) = 'stata kish'
and a.xyz = b.xyz
The "from " (3rd line) part of the above query is giving me ORA-00936 Missing EXPRESSION error. Please Help me
NOTE :: rrfh table contains no data.
Remove the comma?
select /*+USE_HASH( a b ) */ to_char(date, 'MM/DD/YYYY HH24:MI:SS') as LABEL,
ltrim(rtrim(substr(oled, 9, 16))) as VALUE
from rrfh a, rrf b
where ltrim(rtrim(substr(oled, 1, 9))) = 'stata kish'
and a.xyz = b.xyz
Have a look at FROM
SELECTING from multiple tables You can include multiple tables in the
FROM clause by listing the tables with a comma in between each table
name
Remove the coma at the end of your SELECT statement (VALUE,), and also remove the one at the end of your FROM statement (rrf b,)
This answer is not the answer for the above mentioned question but it is related to same topic and might be useful for people searching for same error.
I faced the same error when I executed below mentioned query.
select OR.* from ORDER_REL_STAT OR
problem with above query was OR is keyword so it was expecting other values when I replaced with some other alias it worked fine.
update INC.PROV_CSP_DEMO_ADDR_TEMP pd
set pd.practice_name = (
select PRSQ_COMMENT FROM INC.CMC_PRSQ_SITE_QA PRSQ
WHERE PRSQ.PRSQ_MCTR_ITEM = 'PRNM'
AND PRSQ.PRAD_ID = pd.provider_id
AND PRSQ.PRAD_TYPE = pd.prov_addr_type
AND ROWNUM = 1
)
This happens every time you insert/ update and you don't use single quotes. When the variable is empty it will result in that error. Fix it by using ''
Assuming the first parameter is an empty variable here is a simple example:
Wrong
nvl( ,0)
Fix
nvl('' ,0)
Put your query into your database software and check it for that error. Generally this is an easy fix