Monday 26 September 2011

Sorting with select * from

Recently I had a question from someone who was using a local function which took a delimited string as input and split it into values in a table that was defined as a type like

TYPE V_STRING_T IS TABLE OF VARCHAR2(32767) INDEX BY BINARY_INTEGER

The function used the PIPELINED attribute so the function could be used in an SQL select statement. The function declaration looked like

FUNCTION STR_TO_TAB_PIPELINED(
                        p_string        IN VARCHAR2,
                        p_delimiter     IN VARCHAR2)
RETURN string_array_t PIPELINED;

So an example SQL showing how it might be used is.

SELECT  * 
FROM TABLE(str_to_tab_pipelined('cat,dog,horse',','))

which was all good until there was requirement to have a set of numbers passed in and then sort them as if they were numbers not strings. So basically to add an 'order by to_number'

We can't use a table alias and you can't do something like

SELECT  * 
FROM TABLE(str_to_tab_pipelined('1,5,8,11,4,67,3',','))
ORDER BY to_number(1)

Looking at this I noticed some IDE tools called the column in the query 'column_value'. So I took a chance and tried

SELECT  * 
FROM TABLE(str_to_tab_pipelined('1,5,8,11,4,67,3',','))
ORDER BY to_number(column_value)

And it worked. I did some research and saw the pseudo column 'column_value' is used in XML processing but didn't find mention of using it in this sort of context.