I know this has been answered to some degree with PHP and MYSQL, but I was wondering if someone could teach me the simplest approach to splitting a string (comma delimited) into multiple rows in Oracle 10g (preferably) and 11g.
The table is as follows:
Name | Project | Error
108 test Err1, Err2, Err3
109 test2 Err1
I want to create the following:
Name | Project | Error
108 Test Err1
108 Test Err2
108 Test Err3
109 Test2 Err1
I've seen a few potential solutions around stack, however they only accounted for a single column (being the comma delimited string). Any help would be greatly appreciated.
I think the best way i connect by and regexp function
SOURCE
I had the same problem, and xmltable helped me:
Starting from Oracle 12c you could use
JSON_TABLE
andJSON_ARRAY
:And query:
Output:
db<>fiddle demo
I would like to propose a different approach using a PIPELINED table function. It's somewhat similar to the technique of the XMLTABLE, except that you are providing your own custom function to split the character string:
Results:
The problem with this type of approach is that often the optimizer won't know the cardinality of the table function and it will have to make a guess. This could be potentialy harmful to your execution plans, so this solution can be extended to provide execution statistics for the optimizer.
You can see this optimizer estimate by running an EXPLAIN PLAN on the query above:
Even though the collection has only 3 values, the optimizer estimated 8168 rows for it (default value). This may seem irrelevant at first, but it may be enough for the optimizer to decide for a sub-optimal plan.
The solution is to use the optimizer extensions to provide statistics for the collection:
Testing the resulting execution plan:
As you can see the cardinality on the plan above is not the 8196 guessed value anymore. It's still not correct because we are passing a column instead of a string literal to the function.
Some tweaking to the function code would be necessary to give a closer estimate in this particular case, but I think the overall concept is pretty much explained here.
The str2tbl function used in this answer was originally developed by Tom Kyte: https://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:110612348061
The concept of associating statistics with object types can be further explored by reading this article: http://www.oracle-developer.net/display.php?id=427
The technique described here works in 10g+.
I'd like to add another method. This one uses recursive querys, something I haven't seen in the other answers. It is supported by Oracle since 11gR2.
It is quite flexible with the splitting character. Simply change it in the
INSTR
calls.i had used the DBMS_UTILITY.comma_to _table function actually its working the code as follows
i had used my own table and column names