What is the string concatenation operator in Oracle? - sql

What is the string concatenation operator in Oracle SQL?
Are there any "interesting" features I should be careful of?
(This seems obvious, but I couldn't find a previous question asking it).

It is ||, for example:
select 'Mr ' || ename from emp;
The only "interesting" feature I can think of is that 'x' || null returns 'x', not null as you might perhaps expect.

There's also concat, but it doesn't get used much
select concat('a','b') from dual;

I would suggest concat when dealing with 2 strings, and || when those strings are more than 2:
select concat(a,b)
from dual
or
select 'a'||'b'||'c'||'d'
from dual

DECLARE
a VARCHAR2(30);
b VARCHAR2(30);
c VARCHAR2(30);
BEGIN
a := ' Abc ';
b := ' def ';
c := a || b;
DBMS_OUTPUT.PUT_LINE(c);
END;
output:: Abc def

There are two ways to concatenate Strings in Oracle SQL. Either using CONCAT function or || operator.
CONCAT function allows you to concatenate two strings together
SELECT CONCAT( string1, string2 ) FROM dual;
Since CONCAT function will only allow you to concatenate two values together. If you want to concatenate more values than two, you can nest multiple CONCAT function calls.
SELECT CONCAT(CONCAT('A', 'B'),'C') FROM dual;
An alternative to using the CONCAT function would be to use the || operator
SELECT 'My Name' || 'My Age' FROM dual;

Using CONCAT(CONCAT(,),) worked for me when concatenating more than two strings.
My problem required working with date strings (only) and creating YYYYMMDD from YYYY-MM-DD as follows (i.e. without converting to date format):
CONCAT(CONCAT(SUBSTR(DATECOL,1,4),SUBSTR(DATECOL,6,2)),SUBSTR(DATECOL,9,2)) AS YYYYMMDD

Related

SQL join strings and coalesce()? [duplicate]

What does || do in SQL?
SELECT 'a' || ',' || 'b' AS letter
|| represents string concatenation. Unfortunately, string concatenation is not completely portable across all sql dialects:
ansi sql: || (infix operator)
mysql: concat ( vararg function ). caution: || means 'logical or' (It's configurable, however; thanks to #hvd for pointing that out)
oracle: || (infix operator), concat ( caution: function of arity 2 only ! )
postgres: || (infix operator)
sql server: + (infix operator), concat ( vararg function )
sqlite: || (infix operator)
hopefully the confusion is complete ...
SELECT 'a' || ',' || 'b' AS letter
will combine a letter.
The result become 'a,b'
It is a concat statement. It will concatenate the two strings.
Here is a helpful post!
What is the difference between "||" operator and concat function in Oracle?
In Oracle, SQLite3, and MySQL, it concatenates strings. Please see the Oracle documentation. The MySQL documentation.
Also, it's part of ANSI SQL, but read this for more information.
It's a concatenation operator. So you would get 'a,b' from that.
I think || will work on most RDBMS's. SQL Server requires the + operator (thanks to HVD for setting me straight!).
in oracle its a shortcut for concatenate
http://docs.oracle.com/cd/B19306_01/server.102/b14200/operators003.htm

Postreg SQL get All Value with quotes from the comma separated

I have Values which are stored like 1,2,3,4,5 in the database.
I want it back like '1','2','3','4','5'.
I am trying with string_agg(format('''%s''', ticker_information.user_groups), ',')
but giving me result '1,2,3,4,5'
Any solution ? Or let me know If I am doing wrong.
Thanks
Try this if you just want a string back with the quotes
WITH sample AS (
SELECT '1,2,3,4,5'::text as test
)
SELECT
'''' || array_to_string(
string_to_array(test, ','),
''','''
) || ''''
FROM sample
You can create an array from your csv string using unnest, wrap the elements with quote_literal() and then aggregate them again. You can achieve this with a subquery ..
SELECT array_to_string(array_agg(i),',') FROM
(SELECT quote_literal(unnest(string_to_array(user_groups,',')))
FROM ticker_information) j (i);
array_to_string
---------------------
'1','2','3','4','5'
Or with a LATERAL :
SELECT array_to_string(array_agg(quote_literal(j.i)),',')
FROM ticker_information,
LATERAL unnest(string_to_array(user_groups,',')) j (i);
array_to_string
---------------------
'1','2','3','4','5'
Another option would be with regular expressions.. but it could get nasty if the elements of your csv contain commas.
Demo: db<>fiddle

Extract number from string with Oracle function

I need to create an Oracle DB function that takes a string as parameter. The string contains letters and numbers. I need to extract all the numbers from this string. For example, if I have a string like RO1234, I need to be able to use a function, say extract_number('RO1234'), and the result would be 1234.
To be even more precise, this is the kind of SQL query which this function would be used in.
SELECT DISTINCT column_name, extract_number(column_name)
FROM table_name
WHERE extract_number(column_name) = 1234;
QUESTION: How do I add a function like that to my Oracle database, in order to be able to use it like in the example above, using any of Oracle SQL Developer or SQLTools client applications?
You'd use REGEXP_REPLACE in order to remove all non-digit characters from a string:
select regexp_replace(column_name, '[^0-9]', '')
from mytable;
or
select regexp_replace(column_name, '[^[:digit:]]', '')
from mytable;
Of course you can write a function extract_number. It seems a bit like overkill though, to write a funtion that consists of only one function call itself.
create function extract_number(in_number varchar2) return varchar2 is
begin
return regexp_replace(in_number, '[^[:digit:]]', '');
end;
You can use regular expressions for extracting the number from string. Lets check it. Suppose this is the string mixing text and numbers 'stack12345overflow569'. This one should work:
select regexp_replace('stack12345overflow569', '[[:alpha:]]|_') as numbers from dual;
which will return "12345569".
also you can use this one:
select regexp_replace('stack12345overflow569', '[^0-9]', '') as numbers,
regexp_replace('Stack12345OverFlow569', '[^a-z and ^A-Z]', '') as characters
from dual
which will return "12345569" for numbers and "StackOverFlow" for characters.
This works for me, I only need first numbers in string:
TO_NUMBER(regexp_substr(h.HIST_OBSE, '\.*[[:digit:]]+\.*[[:digit:]]*'))
the field had the following string: "(43 Paginas) REGLAS DE PARTICIPACION".
result field: 43
If you are looking for 1st Number with decimal as string has correct decimal places, you may try regexp_substr function like this:
regexp_substr('stack12.345overflow', '\.*[[:digit:]]+\.*[[:digit:]]*')
To extract charecters from a string
SELECT REGEXP_REPLACE(column_name,'[^[:alpha:]]') alpha FROM DUAL
In order to extract month and a year from a string 'A0807' I did the following in PL/SQL:
DECLARE
lv_promo_code VARCHAR2(10) := 'A0807X';
lv_promo_num VARCHAR2(5);
lv_promo_month NUMBER(4);
lv_promo_year NUMBER(4);
BEGIN
lv_promo_num := REGEXP_SUBSTR(lv_promo_code, '(\d)(\d)(\d)(\d)');
lv_promo_month := EXTRACT(month from to_date(lv_promo_num, 'MMYY'));
DBMS_OUTPUT.PUT_LINE(lv_promo_month);
lv_promo_year := EXTRACT(year from to_date(lv_promo_num, 'MMYY'));
DBMS_OUTPUT.PUT_LINE(lv_promo_year);
END;

Selecting individual values from csv format in oracle pl sql

I have the following value in a column in Oracle db ('abc', 'xyz')
I want to extract the values separately like abc, xyz by removing ' and (). Is there a way to do it using INSTR and SUBSTR functions?
Thanks
Use this query:
with sample as (select '(''abc'', ''xyz'')' text from dual)
select substr(text,instr(text,'''',1,1) + 1,instr(text,'''',1,2) - instr(text,'''',1,1) - 1),
substr(text,instr(text,'''',1,3) + 1,instr(text,'''',1,4) - instr(text,'''',1,3) - 1)
from sample;
It would help to know what you want to do with the data once parsed. How it could be handled in SQL vs PL/SQL to achieve your requirement could be very different.
That said, here's one way to strip surrounding parens and remove single quotes at the same time during the select using the powerful regexp_replace(source_string, pattern_string, replace_string) :
WITH qry AS (SELECT '(' || '''abc''' || ',' || '''xyz''' || ')' orig_string
FROM dual
)
SELECT regexp_replace(orig_string, '[()'']', '' ) clean_string
FROM qry;
The regexp_replace pattern_string says to match a character class (defind by opening and closing square brackets) containing a left paren or a right paren or a single quote (quoted so Oracle sees it) and the replace_string replaces it with nothing.
Then, to parse the values remaining here's an example from by bag of tricks I got somewhere and tweaked for this case:
set serveroutput on
DECLARE
-- Build a string in the format "('abc','xyz')"
orig_string varchar2(20) := '(' || '''abc''' || ',' || '''xyz''' || ')';
CURSOR cur IS
WITH qry AS (SELECT regexp_replace(orig_string, '[()'']','' ) clean_string
FROM dual
)
SELECT regexp_substr(clean_string, '[^,]+', 1, ROWNUM) element
FROM qry
CONNECT BY LEVEL <= LENGTH(regexp_replace (clean_string, '[^,]+')) + 1;
BEGIN
FOR rec IN cur LOOP
dbms_output.put_line('Element:' || rec.element);
END LOOP;
END;
It basically loops through the elements and prints them. I'm sure you can adapt this to your situation.

Oracle: SQL query that returns rows with only numeric values

I have a field (column in Oracle) called X that has values like "a1b2c3", "abc", "1ab", "123", "156"
how do I write an sql query that returns me only the X that hold pure numerical values = no letters? from the example above would be „123“ and „156“
select X
from myTable
where ...??
You can use the REGEXP_LIKE function as:
SELECT X
FROM myTable
WHERE REGEXP_LIKE(X, '^[[:digit:]]+$');
Sample run:
SQL> SELECT X FROM SO;
X
--------------------
12c
123
abc
a12
SQL> SELECT X FROM SO WHERE REGEXP_LIKE(X, '^[[:digit:]]+$');
X
--------------------
123
SQL>
If the only characters to consider are letters then you can do:
select X from myTable where upper(X) = lower(X)
But of course that won't filter out other characters, just letters.
Since Oracle 12c (at least) there has been a built-in function to check whether a character value is numeric: VALIDATE_CONVERSION
select X from myTable where validate_conversion(X as number) = 1
If you use Oracle 10 or higher you can use regexp functions as codaddict suggested. In earlier versions translate function will help you:
select * from tablename where translate(x, '.1234567890', '.') is null;
More info about Oracle translate function can be found here or in official documentation "SQL Reference"
UPD: If you have signs or spaces in your numbers you can add "+-" characters to the second parameter of translate function.
What about 1.1E10, +1, -0, etc? Parsing all possible numbers is trickier than many people think. If you want to include as many numbers are possible you should use the to_number function in a PL/SQL function. From http://www.oracle-developer.net/content/utilities/is_number.sql:
CREATE OR REPLACE FUNCTION is_number (str_in IN VARCHAR2) RETURN NUMBER IS
n NUMBER;
BEGIN
n := TO_NUMBER(str_in);
RETURN 1;
EXCEPTION
WHEN VALUE_ERROR THEN
RETURN 0;
END;
/
The complete list of the regexp_like and other regexp functions in Oracle 11.1:
http://66.221.222.85/reference/regexp.html
In your example:
SELECT X
FROM test
WHERE REGEXP_LIKE(X, '^[[:digit:]]$');
You can use following command -
LENGTH(TRIM(TRANSLATE(string1, '+-.0123456789', '')))
This will return NULL if your string1 is Numeric
your query would be -
select * from tablename
where LENGTH(TRIM(TRANSLATE(X, '+-.0123456789', ''))) is null