Set plsql parameters partially - sql

I need to create a query that when i enter partially the value of a parameter until"/" is shown it displays all the row sequences with that parameter in the first part before "/"
I enter as a parameter: pwd
The result of query should be:
pwd/1
pwd/2
pwd/3....

If you have a bind variable :parameter then:
SELECT *
FROM table_name
WHERE value LIKE :parameter || '/%'
So for some test data:
CREATE TABLE table_name ( id, value ) AS
SELECT 1, 'pwd/1' FROM DUAL UNION ALL
SELECT 2, 'pwd/2' FROM DUAL UNION ALL
SELECT 3, 'pwdtest/1' FROM DUAL;
If :parameter is pwd then the output is:
ID | VALUE
-: | :----
1 | pwd/1
2 | pwd/2
db<>fiddle here

Related

Oracle : Select only particular value from a row

I have a like below
data :
1234=A||1456=B||1789=C
1245=||1234=V
1234,1133
1456=||1234=1,234||1234
so i wanted to remove all the value after = and before | except for 1234.
expected data :
1234=A||1456=||1789=
1245=||1234=V
1234,1133
1456=||1234=1,234||1234
You can use:
SELECT REGEXP_REPLACE(
value,
'(^|\|)((1234=.*?)|(\d+=).*?)(\||$)',
'\1\3\4\5'
) AS value
FROM table_name
Which, for the sample data:
CREATE TABLE table_name ( value ) AS
SELECT '1234=A||1456=B||1789=C' FROM DUAL UNION ALL
SELECT '1245=||1234=V' FROM DUAL UNION ALL
SELECT '1234,1133' FROM DUAL UNION ALL
SELECT '1456=||1234=1,234||1234' FROM DUAL;
Outputs:
VALUE
1234=A||1456=||1789=
1245=||1234=V
1234,1133
1456=||1234=1,234||1234
sqlfiddle here

Oracle regex to extract string between first pair of < and > brackets

I am have been assigned a task to parse a string (which is essentially in XML format) and I need to extract the name of the first tag in the string
eg: string '<column><data-type>string</data-type>.............'
or '<filter><condition>....</condition>...............'
or
'......................'
the string keeps changing but I am only interested in the first tag, I would like to get the output like:
column,
filter,
query
i have tried regexp_substr(string,'^<(.+)>',1,1,null,1) and some similer variations but they don't seem to be working cosistently.
Please help.
If you have XML data then use a proper XML parser:
SELECT XMLQUERY( '/*/name()' PASSING XMLTYPE(value) RETURNING CONTENT ) AS tag_name
FROM table_name
Which for the sample data:
CREATE TABLE table_name ( value CLOB );
INSERT INTO table_name ( value )
SELECT '<column><data-type>string</data-type></column>' FROM DUAL UNION ALL
SELECT '<filter><condition>....</condition></filter>' FROM DUAL UNION ALL
SELECT '<query />' FROM DUAL UNION ALL
SELECT '<has_attributes attr1="do not return this" attr2="<or> this" />' FROM DUAL
Outputs:
| TAG_NAME |
| :------------- |
| column |
| filter |
| query |
| has_attributes |
db<>fiddle here
You are looking for any character between the bounds -- and that includes '>'. So, just exclude the terminating character:
select regexp_substr(string,'^<([^>]+)>',1,1,null,1)
from (select '<column><data-type>string</data-type>.............' as string from dual union all
select '<filter><condition>....</condition>...............' from dual
) x;

oracle sql contain

I have table with values in columns like
colname
TMC_MCH,OTA_MCH,CONSOL_MCH,RETAIL_MCH,TOUROP_MCH,SPEC_MCH,QRACTO_MCH
RETAIL_MCH
RETAIL_MCH,CONSOL_MCH
CONSOL_MCH
OTA_MCH
I need to run query to fetch all rows contains RETAIL_MCH or CONSOL_MCH.
if i run query below i get result as below
select * from table111 where
(CONTAINS(table111.colname, 'RETAIL,CONSOL' , 1) > 0)
TMC_MCH,OTA_MCH,CONSOL_MCH,RETAIL_MCH,TOUROP_MCH,SPEC_MCH,QRACTO_MCH
RETAIL_MCH
RETAIL_MCH,CONSOL_MCH
CONSOL_MCH
but I need to exact search including underscore "_"
select * from table111 where
(CONTAINS(table111.colname, 'RETAIL_MCH,CONSOL_MCH' , 1) > 0)
CONTAINS is an Oracle text function, you can escape the underscore:
SELECT *
FROM table111
WHERE CONTAINS( colname, 'RETAIL\_MCH,CONSOL\_MCH', 1 ) > 0
Or, if you want to pass the string in unescaped then you could use REPLACE to add the escape characters:
SELECT *
FROM table111
WHERE CONTAINS( colname, REPLACE ( 'RETAIL_MCH,CONSOL_MCH', '_', '\_' ), 1 ) > 0
Which, for the sample data:
CREATE TABLE table111 ( colname ) AS
SELECT 'TMC_MCH,OTA_MCH,CONSOL_MCH,RETAIL_MCH,TOUROP_MCH,SPEC_MCH,QRACTO_MCH' FROM DUAL UNION ALL
SELECT 'RETAIL_MCH' FROM DUAL UNION ALL
SELECT 'RETAIL_MCH,CONSOL_MCH' FROM DUAL UNION ALL
SELECT 'CONSOL_MCH' FROM DUAL UNION ALL
SELECT 'OTA_MCH' FROM DUAL;
CREATE INDEX table111__colname__textidx ON table111(colname) INDEXTYPE IS CTXSYS.CONTEXT;
Outputs:
| COLNAME |
| :------------------------------------------------------------------- |
| TMC_MCH,OTA_MCH,CONSOL_MCH,RETAIL_MCH,TOUROP_MCH,SPEC_MCH,QRACTO_MCH |
| RETAIL_MCH |
| RETAIL_MCH,CONSOL_MCH |
| CONSOL_MCH |
db<>fiddle here
It would be probably simpler if you said which result you want. The way I understood it, maybe this helps:
select *
from table111
where instr(colname, 'RETAIL_MCH') > 0
or instr(colname, 'CONSOL_MCH') > 0;
OR might need to be substituted by AND (depending on what you want).
If you want either value, you would use:
where CONTAINS(table111.colname, 'RETAIL|CONSOL' , 1) > 0
If you want both:
where CONTAINS(table111.colname, 'RETAIL&CONSOL' , 1) > 0
You should pass the value in with the operator you want, instead of ,.

Replace a column value in a string delimiter using Oracle SQL

I have a string value in a column in a table like
001|3880000005376|Personal ID| ||15-MAY-2006
and I want to replace the fourth value by another string value 'ABCDEF' , can it be possible by a single update or by PL/SQL program?
Here's one option:
SQL> with test (id, col) as
2 (select 1, '001|3880000005376|Personal ID| ||15-MAY-2006' from dual union all
3 select 2, '002|3880000005376|Personal ID|XXX||15-MAY-2007' from dual
4 )
5 select
6 id,
7 regexp_replace(col, '[^|]+', 'NEW STRING', 1, 4) result
8 from test;
ID RESULT
---------- ------------------------------------------------------------
1 001|3880000005376|Personal ID|NEW STRING||15-MAY-2006
2 002|3880000005376|Personal ID|NEW STRING||15-MAY-2007
SQL>
It replaces 4th occurrence of the '[^|]+' pattern with a NEW STRING value.

regexp_substr with LIKE as search condition

Thank you mathguy for your suggestion and assistance. The example you provided is a near perfect description of the issue. That being said I've used and edited your text to help describe this issue:
I receive a string that contains comma delimited digits in the form of 18656, 16380, 16424 (call this param1). The string only contains commas and digits.
In mytable I have a column named t with values such as 18656.01.02, 10.02.02, 16380.02.03, 16424.05.66, 16424.55.23.14.
I want to select the all rows that match all of the comma-separated digits in param1; where the first numeric component in column t is like 18656, 16380, 16424. Is there a way to use regexp_substr in this case.
Where param1 = 18656, 16380, 16424
the following works:
select * from mytable where t.mycolumn IN
(
(SELECT regexp_substr(:param1,'[^,]+', 1, level) as NUMLIST
FROM DUAL
CONNECT BY regexp_substr(:param1, '[^,]+', 1, level) IS NOT NULL)
);
How to use wildcard if data I seek from t.mycolumn = 18656.00.01, 16380.09.34, 16424.023.8
Can LIKE be used as search criteria? If possible please provide example.
Obviously, the following will not work but I am hoping to find a solution.
select * from mytable where t.mycolumn LIKE
(
(SELECT regexp_substr(:param1||'%','[^,]+', 1, level) as NUMLIST
FROM DUAL
CONNECT BY regexp_substr(:param1||'%', '[^,]+', 1, level) IS NOT NULL)
);
Assumptions:
There is a table named mytable with a column named t which
contains values as follows:
SELECT * FROM mytable;
T |
---------------|
18656.01.02 |
10.02.02 |
16380.02.03 |
16424.05.66 |
16424.55.23.14 |
There is a string received as a parameter, that contains comma delimited digits in the form of 18656, 16380, 16424. The string only contains commas and digits. This string is parsed into indyvidual rows with a help of a query that looks similar to the folowing one:
SELECT regexp_substr(param1,'[^,]+', 1, level) as NUMLIST
FROM (
select '18656,16380,16424' as param1 FROM DUAL
)
CONNECT BY regexp_substr(param1, '[^,]+', 1, level) IS NOT NULL
;
NUMLIST |
--------|
18656 |
16380 |
16424 |
Requirement
Can LIKE be used as search criteria? If possible please provide
example.
LIKE keyword is used below as a condition in JOIN ... ON clause:
SELECT * FROM mytable
WHERE t IN (
SELECT t
FROM mytable m
JOIN (
SELECT regexp_substr(param1,'[^,]+', 1, level) as NUMLIST
FROM (
select '18656,16380,16424' as param1 FROM DUAL
)
CONNECT BY regexp_substr(param1, '[^,]+', 1, level) IS NOT NULL
) x
ON m.t LIKE '%' || x.NUMLIST || '%'
)
T |
---------------|
18656.01.02 |
16380.02.03 |
16424.05.66 |
16424.55.23.14 |