pls help me with this oracle sql query - sql

I have to write a oracle SQL query where I have to check that length of string is 64 or not if it's 64 like in this string
'Lst021_23-FehlerDatenprotokoll.AenDienst2019.06.11_08.48.42.tx' then extension of the string should be txt and we have to remove the part of string upto - also
So for the string
'Lst021_23-FehlerDatenprotokoll.AenDienst2019.06.11_08.48.42.tx' output will be
FehlerDatenprotokoll.AenDienst2019.06.11_08.48.42.txt
i am trying to write this query
SELECT 'Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx'FROM Dual;
CASE
WHEN LENGTH('Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx')=64 THEN CONCAT('SUBSTR('Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx',11,53)','t')
END
CASE;

You have syntax issue in the script. Try this way
SELECT
CASE
WHEN LENGTH('Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx') = 64
THEN CONCAT(SUBSTR('Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx',11,53),'t')
ELSE 'Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx'
END
FROM Dual;

Prefer writing your string only once :
with t( str ) as
(
select 'Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx' from dual
)
select decode(length(str), 64, concat(str,'t')) as "File Name"
from t;
File Name
-----------------------------------------------------------------
Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.txt
Demo

How about this? If length is 64, then:
take a substring from the first hyphen (-) to the end of the string
apply regexp_replace and substitute the last "word" (\w+$) with txt (as you said that extension has to be txt)
Here we go:
SQL> with test (id, col) as
2 (select 1, 'Lst021_23-Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.tx' from dual
3 union all
4 select 2, 'blabla-Something-else.Which_is_64_characters_long.2019.06.12.txt' from dual
5 union all
6 select 3, 'This will not be "fixed" as it is shorter than 64 chars.exe' from dual
7 union all
8 select 4, 'Yet another nice string-Kein_Fehler.Mitwoch.2019.06.13_22.22.com' from dual
9 )
10 select
11 id,
12 case when length(col) = 64 then
13 regexp_replace(substr(col, instr(col, '-') + 1), '\w+$', 'txt')
14 else col
15 end result
16 from test;
ID RESULT
--- -----------------------------------------------------------------
1 Fehler-Datenprotokoll.AenDienst.2019.06.11_08.48.42.txt
2 Something-else.Which_is_64_characters_long.2019.06.12.txt
3 This will not be "fixed" as it is shorter than 64 chars.exe
4 Kein_Fehler.Mitwoch.2019.06.13_22.22.txt
SQL>

Related

REGEXP to validate a specific number

How can I search for a specific number in an array using REGEXP?
I have an array and need to verify if it has a specific number.
Ex: [5,2,1,4,6,19] and I am looking for number 1, but just the number 1 and not any number that contain the digit 1.
I had to do this:
case when REGEXP_INSTR(JSON_QUERY(MY_JSON_COLUMN,'$.path') , '[[]{1}[1][,]')<>0
or REGEXP_INSTR(JSON_QUERY(MY_JSON_COLUMN,'$.path') , '[,]{1}[1][,]{1}')<>0
or REGEXP_INSTR(JSON_QUERY(MY_JSON_COLUMN,'$.path') , '[,]{1}[1][]]')<>0
or REGEXP_INSTR(JSON_QUERY(MY_JSON_COLUMN,'$.path') , '[[]{1}[1][]]') <>0
then 'DIGIT_ONE' else 'NO_DIGIT_ONE'
end
Is there anything simpler?
You can use
(^|\D)1(\D|$)
This will seach for 1 not enclosed with other digits.
See this regex demo.
Details
(^|\D) - start of string or non-digit
1 - a 1 char
(\D|$) - non-digit or end of string.
Do NOT use regular expressions, use a proper JSON parser and then filter for the number you want:
SELECT my_json_column,
CASE
WHEN JSON_EXISTS( my_json_column, '$?(#.path[*] == 1)' )
THEN 'DIGIT ONE'
ELSE 'NO DIGIT ONE'
END AS has_one
FROM table_name;
or (if you are using Oracle 12.1 and cannot use path filter expressions with JSON_EXISTS, which is only available from Oracle 12.2):
SELECT my_json_column,
CASE
WHEN EXISTS(
SELECT 'X'
FROM JSON_TABLE(
t.my_json_column,
'$.path[*]'
COLUMNS (
value NUMBER PATH '$'
)
)
WHERE value = 1
)
THEN 'DIGIT ONE'
ELSE 'NO DIGIT ONE'
END
FROM table_name t;
Which, for the sample data:
CREATE TABLE table_name (
my_json_column CHECK ( my_json_column IS JSON )
) AS
SELECT '{"path":[5,2,1,4,6,19],"not_this_path":[1,2,3,4,5]}' FROM DUAL UNION ALL
SELECT '{"path":[5,2,4,6,19],"not_this_path":[1,2,3,4,5]}' FROM DUAL UNION ALL
SELECT '{"path":[11],"not_this_path":[1]}' FROM DUAL UNION ALL
SELECT '{"path":[2],"not_this_path":[1]}' FROM DUAL UNION ALL
SELECT '{"path":[1,11]}' FROM DUAL;
Both output:
MY_JSON_COLUMN | HAS_ONE
:-------------------------------------------------- | :-----------
{"path":[5,2,1,4,6,19],"not_this_path":[1,2,3,4,5]} | DIGIT ONE
{"path":[5,2,4,6,19],"not_this_path":[1,2,3,4,5]} | NO DIGIT ONE
{"path":[11],"not_this_path":[1]} | NO DIGIT ONE
{"path":[2],"not_this_path":[1]} | NO DIGIT ONE
{"path":[1,11]} | DIGIT ONE
db<>fiddle here
Alternatively, with a little bit more typing (a little bit? Am I kidding?!), splitting the string into rows and comparing values to the search string:
SQL> with test (col) as
2 (select '[5,2,1,4,6,19]' from dual)
3 select t.col,
4 case when '&par_search_string' in
5 (select regexp_substr(substr(col, 2, length(col) - 1), '[^,]+', 1, level) val
6 from test
7 connect by level <= regexp_count(col, ',') + 1
8 )
9 then 'Search string exists'
10 else 'Search string does not exist'
11 end result
12 from test t;
Enter value for par_search_string: 1
COL RESULT
-------------- ----------------------------
[5,2,1,4,6,19] Search string exists
SQL> /
Enter value for par_search_string: 24
COL RESULT
-------------- ----------------------------
[5,2,1,4,6,19] Search string does not exist
SQL>

How to replace numbers in an alphanumeric string with words

I have a table named department_details with a column dept_id which contains values like
10_prod
20_r&d
80_sales
etc. I want a query which will give me output like
ten_prod
twenty_r&d
eighty_sales
etc.
Here's one option:
SQL> with test (col) as
2 (select '10_prod' from dual union all
3 select '20_r&d' from dual union all
4 select '80_sales' from dual
5 )
6 select col,
7 regexp_substr(col, '^\d+') num,
8 to_char(to_date(substr(col, 1, instr(col, '_') - 1), 'j'), 'jsp') wrd,
9 --
10 to_char(to_date(substr(col, 1, instr(col, '_') - 1), 'j'), 'jsp') ||
11 substr(col, instr(col, '_')) result
12 from test;
COL NUM WRD RESULT
-------- -------------------------------- ---------- --------------------
10_prod 10 ten ten_prod
20_r&d 20 twenty twenty_r&d
80_sales 80 eighty eighty_sales
SQL>
What does it do (step-by-step, so that you could follow it):
lines #1 - 5: sample data
line #7: one way to extract the number from the beginning of the string (using regular expressions)
line #8: another way (using substr + instr; probably better). It - additionally - converts it to date using the 'J' format and to character using the JSP format. This is the usual way of spelling numbers
lines #10 - 11: combine spelled number (line #10) with the rest of the string (line #11)
You could do something like this:
with list1 as
(select '10_prod' as val from dual union
select '20_randd' as val from dual union
select '80_sales' as val from dual)
select a.*,
to_char(to_date(substr(val,1,2),'j'), 'jsp')||substr(val,3,20) as text_val
from list1 a

Insert some spaces into a string oracle database

I have a oracle table called MYTABLE , with a prog_model column.
I am trying the CASE (if oracle) to insert some spaces into my prog_model depending of the string length.
My issue is that I'm getting ORA-00936 error missing expression ligne 3 c18 I have no idea where it comes from being a super noob in SQL, any ideas?
Here is my .sql :
SELECT prog_model,
CASE Length(prog_model)
WHEN 11 THEN Insert(' ',2,3,prog_model)
WHEN 12 THEN Insert(' ',2,3,prog_model)
WHEN 13 THEN Insert(' ',2,3,prog_model)
END
FROM MYTABLE;
EDIT:
Basically in prog_model I always have a string from 11 to 14 characters :
if 11 chars , "ABCEFGHIJKL" --> "ABC_ _ _EFGHIKL"
if 12 chars , "ABCEFGHIJKLM" --> "ABC_ _EFGHIJKLM"
I am not aware of an insert() function in Oracle. There is one in MySQL, though. Your error is probably because insert is a keyword.
If you wanted the spaces at the beginning, you would use the lpad() function only:
select lpad(prog_model, 14, ' ')
You seem to want them in the middle. I think this goes like:
select substr(prog_model, 1, 3) || lpad(substr(prog_model, 4), 11, ' ')
I might have the length wrong in the second part. Without sample data, it is challenging to figure out the exact length.
How about this (three approaches to try, including Gordon's substr/lpad):
with demo (prog_model) as
( select 'ABCEFGHIJKL' from dual union all
select 'ABCEFGHIJKLM' from dual union all
select 'ABCEFGHIJKLMN' from dual union all
select 'ABCEFGHIJKLMNO' from dual )
select prog_model
, regexp_replace(prog_model,'(...)(.*$)', '\1'|| rpad(' ',14 - length(prog_model)) ||'\2') as result1
, case length(prog_model)
when 11 then regexp_replace(prog_model,'(...)(.*$)', '\1 \2')
when 12 then regexp_replace(prog_model,'(...)(.*$)', '\1 \2')
when 13 then regexp_replace(prog_model,'(...)(.*$)', '\1 \2')
when 14 then prog_model
end as result2
, substr(prog_model,1,3) || lpad(substr(prog_model,4),11) as result3
from demo;
PROG_MODEL RESULT1 RESULT2 RESULT3
-------------- -------------- -------------- --------------
ABCEFGHIJKL ABC EFGHIJKL ABC EFGHIJKL ABC EFGHIJKL
ABCEFGHIJKLM ABC EFGHIJKLM ABC EFGHIJKLM ABC EFGHIJKLM
ABCEFGHIJKLMN ABC EFGHIJKLMN ABC EFGHIJKLMN ABC EFGHIJKLMN
ABCEFGHIJKLMNO ABCEFGHIJKLMNO ABCEFGHIJKLMNO ABCEFGHIJKLMNO

substring Oracle sql

I need to get substring of String in oralce till a character is found. if Character is not found it should show entire string
Ex :
ABC_DEF
XY_Z
PQRS
Expected result is
ABC
XY
PQRS
I tried below query But it will not work in case search charcter "_" is not found.
SELECT SUBSTR('ABC_X', 0, INSTR('ABC_X', '_')-1) AS output
FROM DUAL
If INSTR() didn't find the character, it would return zero. So, we use DECODE to flip it to length of string itself. otherwise use the position that INSTR returns.
SELECT SUBSTR('ABC_X',0,
DECODE(INSTR('ABC_X', '_'),
0,LENGTH('ABC_X'),
INSTR('ABC_X', '_')-1)) AS output
FROM DUAL;
You can use also regular expressions (something like):
SQL> with t as (
2 select 'ABC_DEF' x from dual union all
3 select 'XY_Z' from dual union all
4 select 'PQRS' from dual union all
5 select '_MJU' from dual union all
6 select 'POI_' from dual union all
7 select 'PAS_PIN_APP' from dual union all
8 select 'LIE$#' from dual
9 )
10 select regexp_substr(x, '[^_]*') from t
11 /
REGEXP_SUBSTR(X,'[^_]*')
--------------------------------------------
ABC
XY
PQRS
POI
PAS
LIE$#

SQL function REGEXP_SUBSTR: Regular Expression how to get the content between two characters but not include them

For these strings
RSLR_AIRL19_ID3454_T20030913091226
RSLR_AIRL19_ID3122454_T20030913091226
RSLR_AIRL19_ID34_T20030913091226
How to get the number after ID ?
Or how to get the content between two characters but not include them ?
I use this '/\_ID([^_]+)/' got matches like Array ( [0] => _ID3454 [1] => 3454 )
Is this the right way?
To extract a number after an ID, you could write a similar query.
SQL> with t1 as(
2 select 'RSLR_AIRL19_ID3454_T20030913091226' as col from dual union all
3 select 'RSLR_AIRL19_ID3122454_T20030913091226' from dual union all
4 select 'RSLR_AIRL19_ID34_T20030913091226' from dual
5 )
6 select regexp_substr(col, '^([[:alnum:]]+_){2}ID([[:digit:]]+)_([[:alnum:]]+){1}$', 1, 1, 'i', 2) as ID
7 from t1
8 ;
ID
-------------
3454
3122454
34
Or, if you want to extract digits from a first occurrence of the pattern without verifying if an entire string matches a specific format:
SQL> with t1 as(
2 select 'RSLR_AI_RL19_ID3454_T20030913091226' as col from dual union all
3 select 'RSLR_AIRL19_ID3122454_T20030913091226' from dual union all
4 select 'RSLR_AIRL19_ID34_T20030913091226' from dual
5 )
6 select regexp_substr(col, 'ID([[:digit:]]+)', 1, 1, 'i', 1) as ID
7 from t1
8 ;
ID
--------------
3454
3122454
34
With pcre & perl engines :
ID\K\w+
NOTE
\K "restart" the match.
See http://www.phpfreaks.com/blog/pcre-regex-spotlight-k (php use pcre)