2

Is there a way to dynamically create an alias in pl/sql?

I have a table ABC

Field1    Field2   Field3  Field4
Joe       Doe      $45.00  XXX
Jane      Doe      $77.00  XXX

I created a new table MY_REF

TableName   FieldName    DisplayValue
ABC         Field1       First Name
ABC         Field2       Last Name
ABC         Field3       Tax Amount

I would like to create a proc that would take a table name (as incoming param) and return the data with the custom aliases.

So if I passed in 'ABC' my end result would be:

First Name   Last Name  Tax Amount
Joe          Doe        $45.00
Jane         Doe        $77.00

EDIT: (Attempt based on Metthew's suggestion)

PROCEDURE GET_CUSTOM_DATA (
                             i_TableName  IN  VARCHAR2,
                             o_Refcur OUT SYS_REFCURSOR
                        )
        IS
        query_string VARCHAR2(500);
        BEGIN                       
            SELECT 'SELECT ' || listagg(fieldname || ' AS "' || displayvalue || '"',',') within group (order by null) || ' FROM ' || i_TableName
            INTO query_string
            FROM ABC
            WHERE tablename = i_TableName

            OPEN :o_Refcur FOR query_string;

        END GET_CUSTOM_DATA_DATA;
3
  • I'll keep digging. While I'm new to Oracle I can create a dynamic sql state in Oracle. The creating of the alias is what unsure of.
    – John Doe
    Commented Mar 7, 2017 at 17:39
  • How are you consuming the data? Can your client and environment understand a reference cursor and convert it into results? Or are you looking for something that will return a pure SQL result set that works in any client?
    – Jon Heller
    Commented Mar 7, 2017 at 18:31
  • That is a good point I didn't consider yet. I will need it to come back in a data set then I can call it with the OracleDataAdapter to get the table.
    – John Doe
    Commented Mar 7, 2017 at 18:39

1 Answer 1

3

In Oracle, the number and name of each column in your query must be defined when the query is parsed. Since you want these to be dynamic, then you must build dynamic SQL. Here is an example of how to do that that uses your data model.

The VARIABLE and PRINT commands are SQL*Plus commands, used here only as a convenient way to print the results. You don't need to use SQL*Plus to accomplish this. You could open a PL/SQL SYS_REFCURSOR variable instead.

VARIABLE rc REFCURSOR

DECLARE
  p_table_name VARCHAR2(30) := 'ABC';  -- This is the parameter you pass in
  l_sql VARCHAR2(4000);
BEGIN

SELECT 'SELECT ' || listagg(fieldname || ' AS "' || displayvalue || '"',',') within group (order by null) || ' FROM ' || p_table_name
INTO   l_sql
FROM   my_ref
WHERE  tablename = p_table_name;

OPEN :rc FOR l_sql;

END;
/


PRINT rc

Results:

PL/SQL procedure successfully completed.

First Name                     Last Name                      Tax Amount
------------------------------ ------------------------------ ------------------------------
Joe                            Doe                            $45.00
Jane                           Doe                            $77.00

Response to error

Sorry I seem to have confused things by involving SQL*Plus. To do it in PL/SQL, you don't use the SQL*Plus bind variables. See my commented version of your code, below.

PROCEDURE GET_CUSTOM_DATA (
                         i_TableName  IN  VARCHAR2,
                         o_Refcur OUT SYS_REFCURSOR
                    )
    IS
    query_string VARCHAR2(500);
    l_rc SYS_REFCURSOR;  -- This is in place of the SQL*Plus bind variable
    BEGIN                       
        SELECT 'SELECT ' || listagg(fieldname || ' AS "' || displayvalue || '"',',') within group (order by null) || ' FROM ' || i_TableName
        INTO query_string
        FROM my_ref  -- You had this as ABC.  ABC should be the value of i_TableName
        WHERE tablename = i_TableName

        -- Open into the PL/SQL ref cursor l_rc instead of the SQL*Plus 
        -- bind variable.
        OPEN l_rc FOR query_string;

        -- NOTE: you need to do something with l_rc: pass it back to the
        -- caller or process it yourself.

    END GET_CUSTOM_DATA_DATA;
4
  • Debugging this still isn't working. I added a print statement after the select statement and my query_string variable looks like: " Table ValueQuery String --> SELECT FROM MY_REF"
    – John Doe
    Commented Mar 7, 2017 at 19:05
  • You've got the tables backwards. You should be selecting the query_string from MY_REF and passing in 'ABC' as the value of i_TableName. Commented Mar 7, 2017 at 19:11
  • This is how I am testing it and it still returns: SELECT FROM ABC
    – John Doe
    Commented Mar 7, 2017 at 19:18
  • Make sure you have inserted the column metadata for table ABC into MY_REF, as in your original post, and commit it. Commented Mar 7, 2017 at 19:21

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.