I have a PL/pgSQL function like this (thanks to the guy who made this possible):
CREATE OR REPLACE FUNCTION public.split_string(text, text)
RETURNS SETOF text
LANGUAGE plpgsql
AS $function$
DECLARE
pos int;
delim_length int := length($2);
BEGIN
WHILE $1 <> ''
LOOP
pos := strpos($1,$2);
IF pos > 0 THEN
RETURN NEXT substring($1 FROM 1 FOR pos - 1);
$1 := substring($1 FROM pos + delim_length);
ELSE
RETURN NEXT $1;
EXIT;
END IF;
END LOOP;
RETURN;
END;
$function$
It splits a string with a delimiter. Like this:
select * from split_string('3.584731 60.739211,3.590472 60.738030,3.592740 60.736220', ' ');
"3.584731"
"60.739211,3.590472"
"60.738030,3.592740"
"60.736220"
How can I save the results in a temp_array or temp_table. So I can get the the results in temp_x and split up these points again. Like:
"3.584731"
"60.739211"
"3.590472"
"60.738030"
"3.592740"
"60.736220"
and return the values as double precision
. And all of this should be done in the function.
String.split (String regex, int limit) It allows us to split string specified by delimiter but into a limited number of tokens. The method accepts two parameters regex (a delimiting regular expression) and limit. The limit parameter is used to control the number of times the pattern is applied that affects the resultant array.
What is a delimiter? In Java, delimiters are the characters that split (separate) the string into tokens. Java allows us to define any characters as a delimiter. There are many string split methods provides by Java that uses whitespace character as a delimiter.
Example 1: This example splits a string by 2 separators Comma (, ) and space (‘ ‘) using .split () function. multiple separators. var str = "A, computer science, portal!"; Example 2: This example split the string by number of separators like Comma (, ), equal (=) and colon (:) using multiple .join () and .split () method.
Following are the two variants of split() method in Java: Parameters: regex - a delimiting regular expression Limit - the result threshold Returns: An array of strings computed by splitting the given string. Throws: PatternSyntaxException - if the provided regular expression’s syntax is invalid.
If you need the intermediary step:
SELECT unnest(string_to_array(a, ' '))::float8
-- or do something else with the derived table
FROM unnest(string_to_array('3.584731 60.739211,3.590472 60.738030', ',')) a;
This is more verbose than regexp_split_to_table()
, but may still be faster because regular expressions are typically more expensive. (Test with EXPLAIN ANALYZE
.)
I first split at ','
, and next at ' '
- the reversed sequence of what you describe seems more adequate.
If need be, you can wrap this into a PL/pgSQL function:
CREATE OR REPLACE FUNCTION public.split_string(_str text
, _delim1 text = ','
, _delim2 text = ' ')
RETURNS SETOF float8 AS
$func$
BEGIN
RETURN QUERY
SELECT unnest(string_to_array(a, _delim2))::float8
-- or do something else with the derived table from step 1
FROM unnest(string_to_array(_str, _delim1)) a;
END
$func$ LANGUAGE plpgsql IMMUTABLE;
Or just an SQL function:
CREATE OR REPLACE FUNCTION public.split_string(_str text
, _delim1 text = ','
, _delim2 text = ' ')
RETURNS SETOF float8 AS
$func$
SELECT unnest(string_to_array(a, _delim2))::float8
FROM unnest(string_to_array(_str, _delim1)) a
$func$ LANGUAGE sql IMMUTABLE;
Make it IMMUTABLE
to allow performance optimization and other uses.
Call (using the provided defaults for _delim1
and _delim2
):
SELECT * FROM split_string('3.584731 60.739211,3.590472 60.738030');
Or:
SELECT * FROM split_string('3.584731 60.739211,3.590472 60.738030', ',', ' ');
For top performance, combine translate()
with unnest(string_to_array(...))
:
SELECT unnest(
string_to_array(
translate('3.584731 60.739211,3.590472 60.738030', ' ', ',')
, ','
)
)::float8
You do not need special functions, use built-in regexp_split_to_table
:
SELECT *
FROM regexp_split_to_table(
'3.584731 60.739211,3.590472 60.738030,3.592740 60.736220',
'[, ]') s;
EDIT: I don't see why you wish to stick with PL/pgSQL function if there's a built-in one.
Anyway, consider this example:
WITH s AS
(
SELECT ' ,'::text sep,
'3.584731 60.739211,3.590472 60.738030,3.592740 60.736220'::text str
)
SELECT sep, left(sep,1), right(sep,-1),
str,
translate(str, right(sep,-1), left(sep,1))
FROM s;
This means, that you can:
$1
into translate($1, right($2,-1), left($2,1))
throughout the code. Obviously, plain $2
should be changed to left($2,1)
.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With