getting comma-separated list near 'xx.yy' invalid with dbms_utility.comma_to_table
See How to split comma delimited string into rows
1. REGEXP_SUBSTR approach
SQL> WITH DATA AS(
2 SELECT 'ac_Abc.88,ac_Abc.99,ac_Abc.77' str FROM dual)
3 SELECT regexp_substr(str,'[^,]+',1,level) str
4 FROM DATA
5 CONNECT BY regexp_substr(str, '[^,]+', 1, level) IS NOT NULL
6 /
STR
-----------------------------
ac_Abc.88
ac_Abc.99
ac_Abc.77
SQL>
2. XML approach
SQL> SELECT EXTRACT (VALUE (d), '//row/text()').getstringval () str
2 FROM
3 (SELECT XMLTYPE ( '<rows><row>'
4 || REPLACE ('ac_Abc.88,ac_Abc.99,ac_Abc.77', ',', '</row><row>')
5 || '</row></rows>' ) AS xmlval
6 FROM DUAL
7 ) x,
8 TABLE (XMLSEQUENCE (EXTRACT (x.xmlval, '/rows/row'))) d
9 /
STR
--------------------
ac_Abc.88
ac_Abc.99
ac_Abc.77
3. Table function
SQL> CREATE TYPE test_type
2 AS
3 TABLE OF VARCHAR2(100)
4 /
Type created.
SQL>
SQL> CREATE OR REPLACE
2 FUNCTION comma_to_table(
3 p_list IN VARCHAR2)
4 RETURN test_type
5 AS
6 l_string VARCHAR2(32767) := p_list || ',';
7 l_comma_index PLS_INTEGER;
8 l_index PLS_INTEGER := 1;
9 l_tab test_type := test_type();
10 BEGIN
11 LOOP
12 l_comma_index := INSTR(l_string, ',', l_index);
13 EXIT
14 WHEN l_comma_index = 0;
15 l_tab.EXTEND;
16 l_tab(l_tab.COUNT) := SUBSTR(l_string, l_index, l_comma_index - l_index);
17 l_index := l_comma_index + 1;
18 END LOOP;
19 RETURN l_tab;
20 END comma_to_table;
21 /
Function created.
SQL> sho err
No errors.
SQL>
SQL> SELECT * FROM TABLE(comma_to_table('ac_Abc.88,ac_Abc.99,ac_Abc.77'))
2 /
COLUMN_VALUE
--------------------------------------------------------------------------------
ac_Abc.88
ac_Abc.99
ac_Abc.77
SQL>
4. Pipelined Function
SQL> CREATE OR REPLACE
2 FUNCTION comma_to_table(
3 p_list IN VARCHAR2)
4 RETURN test_type PIPELINED
5 AS
6 l_string LONG := p_list || ',';
7 l_comma_index PLS_INTEGER;
8 l_index PLS_INTEGER := 1;
9 BEGIN
10 LOOP
11 l_comma_index := INSTR(l_string, ',', l_index);
12 EXIT
13 WHEN l_comma_index = 0;
14 PIPE ROW ( SUBSTR(l_string, l_index, l_comma_index - l_index) );
15 l_index := l_comma_index + 1;
16 END LOOP;
17 RETURN;
18 END comma_to_table;
19 /
Function created.
SQL> sho err
No errors.
SQL>
SQL> SELECT * FROM TABLE(comma_to_table('ac_Abc.88,ac_Abc.99,ac_Abc.77'))
2 /
COLUMN_VALUE
--------------------------------------------------------------------------------
ac_Abc.88
ac_Abc.99
ac_Abc.77
comma separated list invalid near.. with comma_to_table
One way is to use CONNECT BY to effectively loop through the string elements. If you run just the query you'll see how this works. The regular expression allows for NULL list elements should they occur.
insert into TEST(col_a)
select regexp_substr('522,33-23,125,658,25,12-500', '(.*?)(,|$)', 1, level, null, 1)
from dual
connect by level <= regexp_count('522,33-23,125,658,25,12-500', ',')+1
parse comma separated string in oracle stored procedure
You can use the following techniques :
REGEXP_SUBSTR approach
SQL> WITH DATA AS(
2 SELECT q'["06b7930e-293f-6604-e053-2176a8c09440","06b7930e-293f-6604-e053-2176a8c09440"]' str
3 FROM dual)
4 SELECT regexp_substr(str,'[^,]+',1,level) str
5 FROM DATA
6 CONNECT BY regexp_substr(str, '[^,]+', 1, level) IS NOT NULL
7 /
STR
-----------------------------------------------------------------------------
"06b7930e-293f-6604-e053-2176a8c09440"
"06b7930e-293f-6604-e053-2176a8c09440"
SQL>
I have answered a similar question here getting "comma-separated list near 'xx.yy' invalid" with dbms_utility.comma_to_table using other approaches like XML, table function, pipelined function.
Remove duplicates from comma separated list with regexp
Based on this link to split a comma separated value into rows, I splitted the string into rows, kept the position of the first occurence, made a distinct a reaggregated the values
with test_string as (
select 1 as id,
'contract, clause 1, Subsection 1.1, contract, clause 1, Subsection 1.2, paragraph (a), contract, clause 1, Subsection 1.2, paragraph (b), contract, clause 2' val
from dual)
select id, listagg(word,', ') WITHIN GROUP (order by position) FROM (
select distinct id, first_value(position) over ( partition by word order by position ) position, word from (
select
distinct t.id,
levels.column_value as position,
trim(regexp_substr(t.val, '[^,]+', 1, levels.column_value)) as word
from
test_string t,
table(cast(multiset(select level from dual connect by level <= length (regexp_replace(t.val, '[^,]+')) + 1) as sys.OdciNumberList)) levels
)
) GROUP BY id
And if you are not interested in keeping the order
with test_string as (
select 1 as id,
'contract, clause 1, Subsection 1.1, contract, clause 1, Subsection 1.2, paragraph (a), contract, clause 1, Subsection 1.2, paragraph (b), contract, clause 2' val
from dual)
select id, listagg(word,', ') WITHIN GROUP (order by 1) FROM (
select
distinct t.id,
trim(regexp_substr(t.val, '[^,]+', 1, levels.column_value)) as word
from
test_string t,
table(cast(multiset(select level from dual connect by level <= length (regexp_replace(t.val, '[^,]+')) + 1) as sys.OdciNumberList)) levels
) GROUP BY id
Pass value stored in a PL/SQL variable into an IN clause
Another way is to make use of Nested tables in conjunction with TABLE operator
create type nt_vr_arr_list is table of number;
DECLARE
vr_arr_list nt_vr_arr_list := nt_vr_arr_list(100, 200, 330);
BEGIN
FOR cx IN (SELECT id, name
FROM tbl_demo
WHERE id IN (SELECT COLUMN_VALUE FROM TABLE(vr_arr_list))) LOOP
DBMS_OUTPUT.put_line('ID: ' || cx.id || ' Name: ' || cx.name);
END LOOP;
END;
How to get all combinations (ordered sampling without replacement) in regex
I wouldn't use Regex for this, as e.g. the requirements "have to be unique" and "have to be in ascending order" can't really be expressed with a regular expression (at least I can't think of a way to do that).
As you also need to have an expression that is identical in Postgres and Oracle, I would create a function that checks such a list and then hide the DBMS specific implementation in that function.
For Postgres I would use its array handling features to implement that function:
create or replace function is_valid(p_input text)
returns boolean
as
$$
select coalesce(array_agg(x order by x) = string_to_array(p_input, ','), false)
from (
select distinct x
from unnest(string_to_array(p_input,',')) as t(x)
where x ~ '^[0-9]+$' -- only numbers
) t
where x::int between 1 and 4 -- the cast is safe as the inner query only returns valid numbers
$$
language sql;
The inner query returns all (distinct) elements from the input list as individual numbers. The outer query then aggregates that back for values in the desired range and numeric order. If that result isn't the same as the input, the input isn't valid.
Then with the following sample data:
with sample_data (input) as (
values
('1'),
('1,2'),
('1,3'),
('1,4'),
('1,2,3'),
('1,2,4'),
('foo'),
('1aa,1234'),
('1,,2,33,444,')
)
select input, is_valid(input)
from sample_data;
It will return:
input | is_valid
-------------+---------
1 | true
1,2 | true
1,3 | true
1,4 | true
1,2,3 | true
1,2,4 | true
foo | false
1aa,1234 | false
1,,2,33,444, | false
If you want to use the same function in Postgres and Oracle you probably need to use returns integer
in Postgres as Oracle still doesn't support a boolean data type in SQL
Oracle's string processing functions are less powerful than Postgres' functions (e.g. no string_to_array or unnest), but you can probably implement a similar logic in PL/SQL as well (albeit more complicated)
Redirect parent page from AJAX loaded tab
Your question isn't totally clear in regards to what you mean by "tab"
Maybe it would work for you to use
top.location.href='$url'
Related Topics
Designing a SQL Schema for a Combination of Many-To-Many Relationship (Variations of Products)
SQL Query Joins Multiple Tables - Too Slow (8 Tables)
Previous Monday & Previous Sunday's Date Based on Today's Date
Using If Else Statement Based on Count to Execute Different Insert Statements
Multiple Array_Agg() Calls in a Single Query
Create Date from Day, Month, Year Fields in MySQL
Check If Null Exists in Postgres Array
T-Sql: Checking for Email Format
Two Single-Column Indexes VS One Two-Column Index in MySQL
What Is the Most Appropriate Data Type for Storing an Ip Address in SQL Server
How to Return a Incremental Group Number Per Group in SQL
Get the First and Last Date of Next Month in MySQL
Select Query with Case Condition and Sum()
Union All VS or Condition in SQL Server Query
Incorrect Syntax Near the Keyword 'With'...Previous Statement Must Be Terminated with a Semicolon
Using Alias in When Portion of a Case Statement in Oracle SQL