Is it possible in PostgreSQL 9.4 (PLPGSQL) to detect if a string contains a certain string including wildcards and get the wildcards, ex.:
IF NEW.my_string CONTAINS 'patternXYZ' THEN
NEW.my_values := getXYZ(my_string)
END IF;
Which would result in NEW.my_values to contain XYZ (which can be anything in the string, but only the 3 characters).
SELECT
CASE
WHEN (NEW.my_string like '%patternXYZ%')
THEN substring(NEW.my_string from '+pattern+')
ELSE '00'
END AS data
FROM my_table;
Pattern should be the parameter for query.
Related
I'm having : delimited column like 1:2:3:. I want to get this into 1,2,3. My query looks like,
select name
from status where id IN (SELECT REPLACE(NEXT_LIST,':',',')
FROM status);
but I got an error
ORA-01722: invalid number
(1, 2, 3, 4) is different from ('1, 2, 3, 4'). IN requires the former, a list of values; you give it the latter, a string.
You have two options mainly:
Build the query dynamically, i.e. get the list first, then use this to build a query string.
Tokenize the string. This can be done with a custom pipelined function or a recursive query, maybe also via some XML functions. Google "Oracle tokenize string" to find a method that suits you.
UPDATE Option #3: Use LIKE as in ':1:2:3:4:' like '%:3:%'
(This requires your next_list to contain only simple numbers separated with colons. No leading zeros, no blanks, no other characters.)
select name
from status
where (select ':' || next_list || ':' from status) like '%:' || id || ':%'
i agreed with Thorsten but i wonder if we just replace one more time would it works? i mean like this:
select name
from status where id IN (SELECT replace(REPLACE(NEXT_LIST,':',','),'''','')
FROM status);
The REPLACE function returns a string, so the nested query returns a list of string values (where colons replaced with commas), but not a list of number values. When Oracle engine interprets id IN (str_value) it tries to cast the str_value to number and raises exception ORA-01722: invalid number because there are cases like '1:2:3' which are definetely unparseable.
The "pure sql" approach leads us to using custom function detecting if a number is in a colon-separated list:
-- you need Oracle 12c to use function in the WITH clause
-- on earlier versions just unwrap CASE statement and put it into query
WITH
FUNCTION in_list(p_id NUMBER, p_list VARCHAR2) RETURN NUMBER DETERMINISTIC IS
BEGIN
RETURN CASE WHEN
instr(':' || p_list || ':', ':' || p_id || ':') > 0
THEN 1 ELSE 0 END;
END;
SELECT *
FROM status
WHERE in_list(id, next_list) = 1;
Here I assume that values in the next_list column are strings containing numbers separated with colon without spaces. In common case you shall modify the function to match specific list formats.
I'm currently trying to check if a string has a special character (value that is not 0 to 9 A to Z a to z), but the inhouse language that I'm currently using has a very limited function to do it (possible but it will take a lot of lines). but I am able to do a query on sql. Now I would like to ask if it is possible to query using the dual table on sql, My plan is to pass the string to variable and this variable will be use on my sql command. Thanks in advance.
Here is what you can use
SELECT REGEXP_INSTR('Test!ing','[^[:alnum:]]') FROM dual;
This will return a number other than 0 whenever your string has anything other than letters or numbers.
You can use TRANSLATE to remove all okay characters from the string. You get back a string containing only undesired characters - or an empty string when there are none.
select translate(
'AbcDefg1234%99.26éXYZ', -- your string
'.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
'.') from dual;
returns: %.é
I use Postgres 8.1. In my sub function I am returning a string which some ID s are concatenated together. And I need to split those ID s and use them in the WHERE clause from main select query.
for example sub function:
subFunction( 'item_id' character varying )RETURNS character varying AS
-- implementation of sub function---
return concatenatedString;
this concatenatedString like this: 23|32|25|234.
And in my main query
SELECT * FROM tableName WHERE id IN (--need to get ids returning from sub function splitting the string--) .
Is there any way that I can split the string returned by sub function and put the result into the IN clause.
Another approach to solve this : Split PostgreSQL Query filtering
As #JustBob says in his comments, your best bet would be to upgrade to a more recent postgresql version, after which you could use regexp_split_to_table, or regexp_split_to_array and then use array operators instead, eg.
SELECT * FROM tablename WHERE id = ANY (regexp_split_to_array(subFunction(...), '\|'));
However, luckily for you, your string resembles an alternation regex, so you might just be able to get away with this:
SELECT * FROM tablename WHERE id::text ~ '^(' || subFunction(...) || ')$';
This will do a regular expression match against a regex looking like this
^(23|32|25|234)$
which will return true if your id value is in the list.
That should work even in 8.1.
So I want to remove the first 4 characters from a string in oracle. Those characters can be different every time.
In my case I need to take away the first 4 characters of an IBAN and put them at the end of the string. I got the part of putting them to the end of the string but I can't get the first 4 characters to be removed. Every solution I find on the internet removes specified characters, not characters from a certain position in the string (1 to 4).
I used the code below to get the first 4 characters to the end of the string and wanted to try something similar for removing them at the front but without success.
SELECT SUBSTR(iban_nummer, 1, 4) INTO iban_substring FROM dual;
iban_nummer := iban_nummer || iban_substring;
See the docs:
substring_length ...
When you do not specify a value for this argument, then the function returns all characters to the end of string. When you specify
a value that is less than 1, the function returns NA.
So iban_nummer := substr(iban_nummer, 5) || substr(iban_nummer, 1,4) should work. The first part selects all characters beginning from the 5th, the second character numbers 1..4.
update table_name set col_name=substr(col_name,5);
try regexp, like:
SELECT regexp_replace(t.iban_nummer,'(.{4})(.*)','\2\1') FROM t;
Alternative way using regexp :
SELECT regexp_replace(t.iban_nummer,'^.{4}(.*)','\2\1') FROM dual;
Input data:
abcdef_fhj_viji.dvc
Expected output:
fhj_viji.dvc
The part to be trimmed is not constant.
Use the REPLACE method
Select REPLACE('abcdef_fhj_viji.dvc','abcde','')
If you want this query for your table :
Select REPLACE(column,'abcde','') from myTable
For update :
UPDATE TABLE
SET column = REPLACE(column,'abcde','')
select substr('abcdef_fhj_viji.dvc',instr('abcdef_fhj_viji.dvc','_')+1) from dual
So, Its all depends on INSTR function, define from which position and which occurrence, you will get the index and pass that index to SUBSTR to get your string.
Since you didn't give a lot of information I'm gonna assume some.
Let's assume you want a prefix of some string to be deleted. A good way to do that is by using Regular Expressions. There's a function called regexp_replace, that can find a substring of a string, depending on a pattern, and replace it with a different string. In PL/SQL you could write yourself a function using regexp_replace, like this:
function deletePrefix(stringName in varchar2) return varchar2 is
begin
return regexp_replace(stringName, '^[a-zA-Z]+_', '');
end;
or just use this in plain sql like:
regexp_replace(stringName, '^[a-zA-Z]+_', '');
stringName being the string you want to process, and the ^[a-zA-Z]+_ part depending on what characters the prefix includes. Here I only included upper- and lowercase letters.