Function output in a select statement

I have written a function(get_cols) which returns the following string (this string is created dynamically from the fuctions depending on the rows of the tables)
the output of the function is;
MAX (CASE WHEN field_code = 'test_pho' THEN VALUE END ) AS test_pho
,MAX (CASE WHEN field_code = 'ESN' THEN VALUE END ) AS ESN
,MAX (CASE WHEN field_code = 'IMSI' THEN VALUE END ) AS IMSI
,MAX (CASE WHEN field_code = 'PHONE_NO' THEN VALUE END ) AS PHONE_NO
What I need to do is to use this as it is in a another select statement like;
(1)
select
empno,
MAX (CASE WHEN field_code = 'test_pho' THEN VALUE END ) AS test_pho
,MAX (CASE WHEN field_code = 'ESN' THEN VALUE END ) AS ESN
,MAX (CASE WHEN field_code = 'IMSI' THEN VALUE END ) AS IMSI
,MAX (CASE WHEN field_code = 'PHONE_NO' THEN VALUE END ) AS PHONE_NO
from my_employee e, my_columns c
where e.emp_no = c.emp_no
and c.emp_no = '100003'
group by empno
function returns the correct output, but when i call the function in the select like below it get it as a whole string and doesn't give the correct output
(2)
select empno, get_cols('100003')
from my_employee e, my_columns c
where e.emp_no = c.emp_no
and c.emp_no = '100003'
how can i get the output of the function to the select as separate line as shown is above(1)
When I get the above output separately and give in the select as above (1) it gives the correct output I want ??
any help please

josleen wrote:
Hi BluShadow,
Your solution seem interesting. Can you explain how can this be used to produce the required output ? Do we need to maintain a separate my_columns table ?Not quite sure what you are asking?
As with any query, the output columns have to be defined at design time, you cannot have the number of columns dynamically generated based on the data. So, if you said you wanted to pivot data from rows to columns and the number of possible values in those rows could change, you cannot pivot those to columns unless you are expecting those values or have allowed for maximum number of values.
Basic example... Let say we have the following data:
SQL> select * from dept;
    DEPTNO DNAME          LOC
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTONAnd we want to pivot that data to put the departments as columns rather than rows. We can simply do something like:
SQL> ed
Wrote file afiedt.buf
  1  select max(decode(deptno,10,dname)) as dname_10
  2        ,max(decode(deptno,10,loc)) as   loc_10
  3        ,max(decode(deptno,20,dname)) as dname_20
  4        ,max(decode(deptno,20,loc)) as   loc_20
  5        ,max(decode(deptno,30,dname)) as dname_30
  6        ,max(decode(deptno,30,loc)) as   loc_30
  7        ,max(decode(deptno,40,dname)) as dname_40
  8        ,max(decode(deptno,40,loc)) as   loc_40
  9* from dept
SQL> /
DNAME_10       LOC_10        DNAME_20       LOC_20        DNAME_30       LOC_30        DNAME_40       LOC_40
ACCOUNTING     NEW YORK      RESEARCH       DALLAS        SALES          CHICAGO       OPERATIONS     BOSTON
SQL>However if a further department is added:
SQL> insert into dept values (50, 'IT SUPPORT', 'LONDON');
1 row created.
SQL> select max(decode(deptno,10,dname)) as dname_10
  2        ,max(decode(deptno,10,loc)) as   loc_10
  3        ,max(decode(deptno,20,dname)) as dname_20
  4        ,max(decode(deptno,20,loc)) as   loc_20
  5        ,max(decode(deptno,30,dname)) as dname_30
  6        ,max(decode(deptno,30,loc)) as   loc_30
  7        ,max(decode(deptno,40,dname)) as dname_40
  8        ,max(decode(deptno,40,loc)) as   loc_40
  9  from dept
10  /
DNAME_10       LOC_10        DNAME_20       LOC_20        DNAME_30       LOC_30        DNAME_40       LOC_40
ACCOUNTING     NEW YORK      RESEARCH       DALLAS        SALES          CHICAGO       OPERATIONS     BOSTON
SQL>we obviously don't get to see the new data, unless we change our query to add this expected additional column(s) in...
SQL> ed
Wrote file afiedt.buf
  1  select max(decode(deptno,10,dname)) as dname_10
  2        ,max(decode(deptno,10,loc)) as   loc_10
  3        ,max(decode(deptno,20,dname)) as dname_20
  4        ,max(decode(deptno,20,loc)) as   loc_20
  5        ,max(decode(deptno,30,dname)) as dname_30
  6        ,max(decode(deptno,30,loc)) as   loc_30
  7        ,max(decode(deptno,40,dname)) as dname_40
  8        ,max(decode(deptno,40,loc)) as   loc_40
  9        ,max(decode(deptno,50,dname)) as dname_50
10        ,max(decode(deptno,50,loc)) as   loc_50
11* from dept
SQL> /
DNAME_10       LOC_10        DNAME_20       LOC_20        DNAME_30       LOC_30        DNAME_40       LOC_40        DNAME_50       LOC_50
ACCOUNTING     NEW YORK      RESEARCH       DALLAS        SALES          CHICAGO       OPERATIONS     BOSTON        IT SUPPORT     LONDON
SQL>Now, rather than having a messy SQL statment with lots of max(decode... statements we can provide a pipelined function to return the same thing...
SQL> ed
Wrote file afiedt.buf
  1  CREATE OR REPLACE TYPE mydepts AS OBJECT
  2  ( dname_10   VARCHAR2(14),
  3    loc_10     VARCHAR2(13),
  4    dname_20   VARCHAR2(14),
  5    loc_20     VARCHAR2(13),
  6    dname_30   VARCHAR2(14),
  7    loc_30     VARCHAR2(13),
  8    dname_40   VARCHAR2(14),
  9    loc_40     VARCHAR2(13),
10    dname_50   VARCHAR2(14),
11    loc_50     VARCHAR2(13)
12* )
13  /
Type created.
SQL> ed
Wrote file afiedt.buf
  1* CREATE OR REPLACE TYPE mydepttable AS TABLE OF mydepts
SQL> /
Type created.
SQL> ed
Wrote file afiedt.buf
  1  CREATE OR REPLACE FUNCTION alldepts RETURN mydepttable PIPELINED IS
  2    v_obj mydepts := mydepts(NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
  3    CURSOR cur_depts IS
  4      select deptno, dname, loc from dept;
  5  BEGIN
  6    FOR i IN cur_depts
  7    LOOP
  8      CASE i.deptno
  9       WHEN 10 THEN v_obj.dname_10 := i.dname; v_obj.loc_10 := i.loc;
10       WHEN 20 THEN v_obj.dname_20 := i.dname; v_obj.loc_20 := i.loc;
11       WHEN 30 THEN v_obj.dname_30 := i.dname; v_obj.loc_30 := i.loc;
12       WHEN 40 THEN v_obj.dname_40 := i.dname; v_obj.loc_40 := i.loc;
13       WHEN 50 THEN v_obj.dname_50 := i.dname; v_obj.loc_50 := i.loc;
14      ELSE NULL;
15      END CASE;
16    END LOOP;
17    PIPE ROW (v_obj);
18    RETURN;
19* END;
SQL> /
Function created.
SQL> select *
  2  from table(alldepts());
DNAME_10       LOC_10        DNAME_20       LOC_20        DNAME_30       LOC_30        DNAME_40       LOC_40        DNAME_50       LOC_50
ACCOUNTING     NEW YORK      RESEARCH       DALLAS        SALES          CHICAGO       OPERATIONS     BOSTON        IT SUPPORT     LONDON
SQL>So, now there is a single function that acts like a table and does the functionality of pivoting the data. What the function actually does to generate the data is entirely up to you whether that is obtaining data from different tables or some PL/SQL code processing to perform some complex algorithmic type thing on the data from a passed in parameter etc. The point of the pipeline function is that it can return multiple columns of data and act as if it is a table that can be queried against, however it still remains that the output columns must be known at design time. This is actually a requirement of the SQL engine, as you cannot make a dynamic function that returns X number of columns based on data.
There is however a technique that can allow you to dynamically generate a number of columns based on data, but it involves getting a little more under the hood of Oracle and interfacing with the ODCI interface, actually using a pipelined funcion technique in conjunction with, in laymans terms, stepping in at the point the query is executing and telling oracle what columns this pipelined function is going to return, but at the same time as defining the returned columns.
An example of doing this is given by AScheffer on this thread: How to pipeline a function with a dynamic number of columns?
... but you really are getting into a complex world if you try and write your queries this way, just to try and make generic queries with dynamic columns.
In essence, the actual business need to actually return a dynamic number of columns is very slim as most applications, whether that is a user facing interface or report generator etc. will be expecting certain data columns to be returned to expected columns or fields within them. If you really want to dynamically pivot data with an unknown number of columns it is usually best to let things like reporting tools deal with this area as that is what they are best at, and don't try and do it within SQL.

Similar Messages

  • Output count of SELECT statement is diff from count(*) of the same query

    Has this ever happened to you?
    I was wondering why some of the items were not appearing in my output. I have this select query:
        SELECT
            bukrs
            gjahr
            hkont
            belnr
            wrbtr
            dmbtr
            matnr
            bschl
            kunnr
            vbeln
            shkzg
        FROM bseg
        INTO CORRESPONDING FIELDS OF TABLE i_output
        FOR ALL ENTRIES IN i_bkpf
        WHERE
            bukrs EQ i_bkpf-bukrs
            AND belnr EQ i_bkpf-belnr
            AND gjahr EQ i_bkpf-gjahr
            AND hkont IN hkont
            AND hkont IN
                ('0004000000',
                '0004000010',
                '0004000020',
                '0004000030',
                '0004000040')
    When I tried to put sample filters (bukrs: 1000; belnr 1800000016; gjahr: 2005; hkont: 4000000), I am getting 3 entries from bseg. But when I tried using SE16 or SE16N, I am getting 6 (which is the expected output). When I modify the same SELECT query to return just the output count, I AM getting 6.
        SELECT count(*)
        FROM bseg
        INTO count
        FOR ALL ENTRIES IN i_bkpf
        WHERE
            bukrs EQ i_bkpf-bukrs
            AND belnr EQ i_bkpf-belnr
            AND gjahr EQ i_bkpf-gjahr
            AND hkont IN hkont
            AND hkont IN
                ('0004000000',
                '0004000010',
                '0004000020',
                '0004000030',
                '0004000040')
    Do you have any idea why this happens? My internal table is a standard table with no header line and no OCCURS statement.
    Kyle

    Hello Kyle,
    Thats because when using FOR ALL ENTRIES, it will delete the duplicates if the records selected dont have all the primary keys specified in the select query. In your first select query, the field BUZEI is missing which makes the records unique. Change your first select query as this and try
    SELECT
            bukrs
            gjahr
            hkont
            belnr
            buzei   -------> Add this and check
            wrbtr
            dmbtr
            matnr
            bschl
            kunnr
            vbeln
            shkzg
        FROM bseg
        INTO CORRESPONDING FIELDS OF TABLE i_output
        FOR ALL ENTRIES IN i_bkpf
        WHERE
            bukrs EQ i_bkpf-bukrs
            AND belnr EQ i_bkpf-belnr
            AND gjahr EQ i_bkpf-gjahr
            AND hkont IN hkont
            AND hkont IN
                ('0004000000',
                '0004000010',
                '0004000020',
                '0004000030',
                '0004000040')
    Vikranth

  • Formatting output from a select statement?

    Hi: a trivial question.
    When I run a select on four fields, it prints the first field in one line and the rest in the second line.
    TYPE
      PROTO CLASS_ID DSTPORT
    BUILT_INBOUND_UDP
         17    50007      53
    Is there a any variable I can configure so that all four fields are printed in the same line?
    TYPE               PROTO CLASS_ID DSTPORT
    BUILT_INBOUND_UDP 17    50007      53Thanks
    Ray

    SQL> SELECT a.owner from all_all_tables a WHERE rownum = 1;
    OWNER
    SYS
    SQL> column owner format a15;
    SQL> SELECT a.owner from all_all_tables a WHERE rownum = 1;
    OWNER
    SYS
    SQL> column owner format a5;
    SQL> SELECT a.owner from all_all_tables a WHERE rownum = 1;
    OWNER
    SYS
    SQL>

  • Calling a user defined function in a select statement

    PLS-00231: function 'F_GET_PROJECT_ID' may not be used in SQL
    I am caling a user defined function 'F_GET_PROJECT_ID' in a select statement and getting the above error .
    Can any one help me to resolve it.
    I can not replace the function with a local variable nor can I assign the output of the function to a variable and use the variable in the sql stmt. cos, the in put parameters of the function comes from the same select statement.
    Please help
    Thanks in advance

    Can you provide your function code? Using a function like that is possible from the below example. I suspect something in your function code.
    SQL> create or replace function sample_func(p_sal number)
      2  return number
      3  is
      4  v_sal number;
      5  begin
      6     v_sal := p_sal+100;
      7     return v_sal;
      8  end;
      9  /
    Function created.
    SQL>
    SQL> select empno, ename, sal, sample_func(sal)
      2  from emp
      3  /
         EMPNO ENAME             SAL SAMPLE_FUNC(SAL)
          7839 KING             5000             5100
          7698 BLAKE            2850             2950
          7782 CLARK            2450             2550
          7566 JONES            2975             3075
          7654 MARTIN           1250             1350
          7499 ALLEN            1600             1700
          7844 TURNER           1500             1600
          7900 JAMES             950             1050
          7521 WARD             1250             1350
          7902 FORD             3000             3100
          7369 SMITH             800              900
          7788 SCOTT            3000             3100
          7876 ADAMS            1100             1200
          7934 MILLER           1300             1400
    14 rows selected.
    SQL>And yeah... your formatted code is this.
    cursor c1 is
       SELECT t.upi_nbr upi_nbr,
              f_get_project_id(l.pay_type_code,
                               l.charge_type_nme,
                               l.charge_code) project_id,
              LAST_DAY(TO_DATE(SUBSTR(t.Year_Month, 5, 2)||'/'||'01'||'/'||SUBSTR(t.Year_Month,1,4),
                               'MM/DD/YYYY'))reporting_period_end_date,
              SUM (c.hours_worked_qty) reported_hrs
       from trs.trs_timesheet@oraprod5 T,
            trs.trs_line@oraprod5 L,
            trs.trs_cell@oraprod5 C
    where T.upi_nbr=L.upi_nbr
    and T.year_month=L.year_month
    and L.row_nbr=C.row_nbr
    and L.upi_nbr=C.upi_nbr
    and L.year_month = C.year_month
    and L.invalid_activity_ind = 'V'
    and rtrim(L.charge_code) is not null
    AND L.Pay_Type_Code<>'REQ'
    and C.Hours_Worked_Qty > 0
    GROUP BY t.upi_nbr,
             t.year_month,
             t.oui_nbr,
             l.charge_code,
             l.activity_detail_code,
             l.charge_type_nme,
             l.pay_type_code;Cheers
    Sarma.

  • Select statement inside function with  into keyword

    Hi Everyone,
    i have a function which contains a select statement
    create or replace
    function fun_1(Table_Name1 in varchar2)
    RETURN VARCHAR2
    is
    VAR_GEN_TYPE NUMBER(10);
    TA_U varchar2(256);
    VAR_DATA_FLAG varchar2(1);
    begin
    select T.FLAG into VAR_GEN_TYPE ,T.DATA_UID_GEN_TYPE into VAR_DATA_FLAG  from T_DYNAMIC_TABLE T  where T.TABLE_NAME=TABLE_NAME1;
    end
    whene ever i am executing this function giving error message: From Keyword  Not Found
    when i change select statement to
    select T.FLAG ,T.DATA_UID_GEN_TYPE into VAR_DATA_FLAG, VAR_GEN_TYPE from T_DYNAMIC_TABLE T where T.TABLE_NAME=TABLE_NAME1;
    then it is working
    why first statements will not work ?
    i.e.,
    select T.FLAG into VAR_GEN_TYPE ,T.DATA_UID_GEN_TYPE into VAR_DATA_FLAG from T_DYNAMIC_TABLE T where T.TABLE_NAME=TABLE_NAME1;
    why in select statement we cannot use into keyword more than one time ?
    Edited by: karteek on Jun 7, 2012 4:23 AM
    Edited by: karteek on Jun 7, 2012 4:24 AM

    select T.FLAG into VAR_GEN_TYPE ,T.DATA_UID_GEN_TYPE into VAR_DATA_FLAG, from T_DYNAMIC_TABLE T where T.TABLE_NAME=TABLE_NAME1;
    into should be only once..
    the syntax should be
    select <column list>
    into
    <variable list>
    from <table name> where <condition>
    --This query shuold return only one row.
    column list count and variable list count should match
    there should be no comma after last variable.andbefore from.

  • Output SELECT statement to CSV file

    Can someone advise the best approach please
    I'm trying to create a CSV file from the output of a SELECT statement in ApEx as a PL/SQL block. I initially thought the simplest approach would be to use SPOOL and then execute the SELECT startment but I think this is a SQLPlus command and can't be used in PL/SQL.
    I then tried using the 'UTL_FILE.PUT' command which works for a single record but I'm not sure how to implement this where the SELECT returns multiple records.
    DECLARE
    fHandler UTL_FILE.FILE_TYPE;
    v_DAT VARCHAR(20);
    v_Handle VARCHAR2(20);
    BEGIN
    SELECT DATA INTO v_DAT FROM HIP_TEST;
    v_Handle := CONCAT('HIP_',CONCAT(TO_CHAR(sysdate,'yyyymmddhhmi'),'.csv'));
    fHandler := UTL_FILE.FOPEN('/nfsacademy/amp/live', v_Handle, 'w');
    UTL_FILE.PUTF(fHandler, v_DAT);
    UTL_FILE.FCLOSE(fHandler);
    EXCEPTION
    WHEN utl_file.invalid_path THEN
    raise_application_error(-20000, 'Invalid path. Create directory or set UTL_FILE_DIR.');
    END;

    Hi,
    You can try this.
    DECLARE
    fHandler UTL_FILE.FILE_TYPE;
    v_DAT VARCHAR(20);
    v_Handle VARCHAR2(20);
    BEGIN
    v_Handle := CONCAT('HIP_',CONCAT(TO_CHAR(sysdate,'yyyymmddhhmi'),'.csv'));
    fHandler := UTL_FILE.FOPEN('/nfsacademy/amp/live', v_Handle, 'w');
    FOR I IN (SELECT DATA FROM HIP_TEST)
    LOOP
         UTL_FILE.PUTF(fHandler, i.data);
    END LOOP;
    UTL_FILE.FCLOSE(fHandler);
    EXCEPTION
    WHEN utl_file.invalid_path THEN
    raise_application_error(-20000, 'Invalid path. Create directory or set UTL_FILE_DIR.');
    END;** NOT TESTED **
    Alternatively you can also use DBMS_OUTPUT.PUT_LINE.
    Regards,
    Avinash
    Edited by: Avinash Tripathi on Nov 17, 2009 3:35 PM

  • How to pass an array to a function from a SELECT statement

    Hi all. I have a problem with passing an array to a function directly from a SELECT statement.
    Here is what I want. If I have a function
    function AAA(arrayVar <ArrayType>) return number;
    I want to be able to call this function this way
    select AAA((2,3,4))
    from dual
    or this way
    select AAA((10,12))
    from dual
    In other words I want to be able to pass an arbitrary number of numbers to the function. And I want this to work in a SELECT statement.
    Does anyone have any ideas how to implement this? What <ArrayType> should I use?(I've read about VARRAY, nested tables in the Oracle documentation but as far as I've understood these array types are meant to be used within PL/SQL blocks).
    I found only this http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:208012348074 through Google but it didn't help me.
    Thank you in advance.

    > What <ArrayType> should I use?
    SQL data types - as 3360 showed above. You cannot use PL/SQL structures and user types in the SQL Engine.
    You can however use all SQL structures and types in PL/SQL.
    Arrays in SQL is created as collection type - basic o-o. The collection type (or class) serve as a container for instantiated objects or scalar type.
    This is covered in detail in [url http://download-uk.oracle.com/docs/cd/B19306_01/appdev.102/b14260/toc.htm]
    Oracle® Database Application Developer's Guide - Object-Relational Features

  • Using procedure in SELECT statement

    I have a select statement that currently uses 4 functions to receive necessary values. All the functions are recursive and returns values from the same row.
    What I would like to do is replace these for function calls with 1 procedure. Does anybody know if it possible to use a procedure in this way inside a select statement?
    If so, do you have the syntax for doing this?
    E.g
    SELECT
    Mdbrd_Pkg.calculate_fixed_charge_fn(in_rc_id, ap.CONFIGSET_ID) AS FIXED_CHARGE,
    Mdbrd_Pkg.calculate_charge_rate_fn(in_rc_id, ap.CONFIGSET_ID) AS CHARGE_RATE,
    Mdbrd_Pkg.tax_liable_fn(in_rc_id, ap.CONFIGSET_ID) AS TAX_LIABLE,
    Mdbrd_Pkg.charge_unit_fn( in_rc_id, ap.CONFIGSET_ID) AS CHARGEUNIT_ID
    FROM .....

    This cannot be done. The part of the function used in the SELECT statement is the return value: procedures don't have return values (that's what makes tham procedures and not functions).
    Obviously I don't know what your code does, but you should consider putting them into a single function that returns a TYPE with four attributes and then using the TABLE() function to cast them into something you could reference in the FROM clause of a correlated sub-query. Sounds a bit messy though.
    Do these functions actually select data? Where does the recursion fit in?
    Cheers, APC

  • Using a varchar field to select statement

    Hi all
    I have a single row and single column table
    T(command varchar2(4000))
    and the row is
    sno,name
    And I have another table T1(sno number,name varchar)
    Now can any body tell how can i use command column in table T to query T1 to get sno,name from T1
    I am looking for a select statement like this
    select (select command from T) from T1;
    but it is printing out the data in T i mean sno, name
    This is a copy of thread Selecting output of a select statement
    but explained more clearly
    Thanks,
    ganesh.

    I don't know why your tables are designed like this but what I think you want to do is join T1 with the data in T.
    select sno, name from T1
    where sno in (select substr(command,0,instr(command,',')-1) from T)
    and name in (select substr(command,instr(command,',')+1) from T);
    substr returns a string up to a position
    instr returns the position of a string
    and the other post you refer to as about as confusing as your one.

  • How to generate mutiple Results for multiple SQL SELECT statements

    I just downloaded SQL Developer 1.5 and play around with it.
    On a daily basis, I need run 4 different SELECT statements and dump the output of each SELECT into an CSV file and send to some users. In SQL Navigator, I can select all 4 SELECT statements and execute them at same time. Once all complete, I will see 4 tabs, each represent the output for each SELECT statement. Then I can export output from each tab into a CSV file.
    It seems that SQL Developer 1.5 still can't run mutiple SELECT statements and display the output of each statement into a separate "Results" tab so that I can export the data into multiple CSV files easily.
    Right now, I have to hightlight each SELECT statement and press F9, then export the output data into CSV.
    I wish I can execute 4 SELECT statements all in once on SQL Developer and get all the output data and export 4 times into 4 CSV files.
    Thanks!
    Kevin

    How about doing it as a set of tabs within the Resuls Tab?
    So you would have your Top row of tabs:
    Results, Script Output, Explain, AutoTrace, DBMS Output and OWA Output
    Then When you have the Results tab selected you could have a row of tabs beneath the Top row with one tab for each result set. Switching between result sets should switch which section of SQL is highlighted as the "Current SQL".
    A similar mechinism could be employed for each of the top level tabs where it makes sense to have multiple output tabs.
    A further refinement of this feature might be to allow the result tabs to be dockable within the parent tab so that multiple result tabs can be viewed simultaneously. This way 2 or more explain plans (for example) could be visually compared without requiring the code to exist in two separate code panes.

  • Output of value returned from function in SELECT statement ??

    Hi
    I have created the below function
    create or replace
    FUNCTION jc_test
    RETURN VARCHAR2
    IS myrec VARCHAR2(270);
    BEGIN
    SELECT RPAD('*',270,'*')
    INTO myrec
    FROM DUAL ;
    RETURN myrec;
    END ;
    and I executed the SELECT statement in Oracle SQL developer as a script
    select
    LENGTH(jc_test()) len
    *,jc_test() rec*
    from dual ;
    I get exact output as below
    LEN REC
    270 ******************************************************************************************************************************************************************************************************************************************************************************
    So here LEN is correctly shown as 270 characters but when I see the astrisk's (also appended with spaces ) its total length is 4000 characters
    Can anyone give their thoughts on this.
    Its fine if I run as normal, i mean not as a script.
    Regards
    jc
    Edited by: JC on Jun 16, 2011 11:25 AM

    Hi,
    So here LEN is correctly shown as 270 charactersYes, correct
    but when I see the astrisk's (also appended with spaces ) its total length is 4000 charactersNo buts. It is not padded. That is just how it is displayed by your tool. In SQL*Plus this is controlled by LINESIZE and COLUMN
    SQL> create or replace function dummy return varchar2 as begin return null; end;
      2  /
    Function created.
    SQL> select dummy from dual;
    D
    X
    SQL> select dummy() from dual;
    DUMMY()
    SQL> col "dummy()" for a10
    SQL> select dummy() from dual;
    DUMMY()
    SQL>P.S: It is a really bad idea to create your own wrapper functions, built-in functions. Hopefully you are not really doing that?
    Regards
    Peter

  • Return multiple values from a function to a SELECT statement

    I hope I've provided enough information here. If not, just let me know what I'm missing.
    I am creating a view that will combine information from a few tables. Most of it is fairly straightforward, but there are a couple of columns in the view that I need to get by running a function within a package. Even this is fairly straightforward (I have a function named action_date in a package called rp, for instance, which I can use to return the date I need via SELECT rp.action_date(sequence_number).
    Here's the issue: I actually need to return several bits of information from the same record (not just action_date, but also action_office, action_value, etc.) - a join of the tables won't work here as I'll explain below. I can, of course, run a separate function for each statement but that is obviously inefficient. Within the confines of the view select statement however, I'm not sure how to return each of the values I need.
    For instance, right now, I have:
    Table1:
    sequence_number NUMBER(10),
    name VARCHAR(30),
    Table2:
    Table1_seq NUMBER(10),
    action_seq NUMBER(10),
    action_date DATE,
    action_office VARCHAR(3),
    action_value VARCHAR(60),
    I can't simply join Table1 and Table2 because I have to do some processing in order to determine which of the matching returned rows I actually need to select. So the package opens a cursor and processes each row until it finds the one that I need.
    The following works but is inefficient since all of the calls to the package will return columns from the same record. I just don't know how to return all the values I need into the SELECT statement.
    CREATE VIEW all_this_stuff AS
    SELECT sequence_number, name,
    rp.action_date(sequence_number) action_date,
    rp.action_office(sequence_number) action_office,
    rp.action_value(sequence_number) action_value
    FROM table1
    Is there a way to return multiple values into my SELECT statement or am I going about this all wrong?
    Any suggestions?
    Thanks so much!

    Hi,
    What you want is a Top-N Query , which you can do using the analytic ROW_NUMBER function in a sub-query, like this:
    WITH     got_rnum     AS
         SELECT     action_seq, action_dt, action_office, action_type, action_value
         ,     ROW_NUMBER () OVER ( ORDER BY  action_date
                                   ,            action_seq
                             ,            action_serial
                           ) AS rnum
         FROM     table2
         WHERE     action_code     = 'AB'
         AND     action_office     LIKE 'E'     -- Is this right?
    SELECT     action_seq, action_dt, action_office, action_type, action_value
    FROM     got_rnum
    WHERE     rnum     = 1
    ;As written, this will return (at most) one row.
    I suspect you'll really want to get one row for each group , where a group is defined by some value in a table to which you're joining.
    In that case, add a PARTITION BY clause to the ROW_NUMBER function.
    If you'd post a little sample data (CREATE TABLE and INSERT statements), I could show you exactly how.
    Since I don't have your tables, I'll show you using tables in the scott schema.
    Here's a view that has data from the scott.dept table and also from scott.emp, but only for the most senior employee in each department (that is, the employee with the earliest hiredate). If there happens to be a tie for the earliest hiredate, then the contender with the lowest empno is chosen.
    CREATE OR REPLACE VIEW     senior_emp
    AS
    WITH     got_rnum     AS
         SELECT     d.deptno
         ,     d.dname
         ,     e.empno
         ,     e.ename
         ,     e.hiredate
         ,     ROW_NUMBER () OVER ( PARTITION BY  d.deptno
                                   ORDER BY          e.hiredate
                             ,                e.empno
                           ) AS rnum
         FROM     scott.dept     d
         JOIN     scott.emp     e     ON     d.deptno     = e.deptno
    SELECT     deptno
    ,     dname
    ,     empno
    ,     ename
    ,     hiredate
    FROM     got_rnum
    WHERE     rnum     = 1
    SELECT     *
    FROM     senior_emp
    ;Output:
    .    DEPTNO DNAME               EMPNO ENAME      HIREDATE
            10 ACCOUNTING           7782 CLARK      09-JUN-81
            20 RESEARCH             7369 SMITH      17-DEC-80
            30 SALES                7499 ALLEN      20-FEB-81 
    By the way, one of the conditions in the query you posted was
    action_office     LIKE 'E'which is equivalent to
    action_office     = 'E'(LIKE is always equivalent to = if the string after LIKE doesn't contain any wildcards.)
    Did you mean to say that, or did you mean something like this:
    action_office     LIKE 'E%'instead?

  • Using TRIM function in select statement

    Hi All,
    I'm using the TRIM function in my select statement to eliminate the white spaces.
    But while using in select the TRIM function is not working in SQL*PLUS client(The query returns the white spaces also)
    Kindly provide some pointers regarding the issue.........
    I want to get only the data without the spaces in select statement
    Regards,
    Mohan

    Hi, Mohan,
    SQL*Plus always pads columns to make them line up nicely.
    If you have a column declared as VARCHAR2 (20), then SQL*Plus will normally display 20 characters for that column, even in the maximum actual length is, say, 5 (or even if the column always happens to be NULL).
    If you want the output to include only the actual data, without the padding that SQL*Plus adds, then concatenate all the columns into one big string column.
    People often do something like the following to generate a CSV file, with no exta spaces:
    SELECT       TO_CHAR (empno)
    || ',' || ename
    || ',' || job
    || ',' || TO_CHAR (deptno)
    || ',' || TO_CHAR (hiredate, 'DD-Mon-YYYY')     AS all_data
    FROM          scott.emp;

  • Using Column Name returned by function in SELECT statement

    Hi
    Output from my function (RETURN data type is VARCHAR2) is column name. I want to use it directly in my SELECT statement. Below is simplified example of this:
    --- Function
    CREATE OR REPLACE FUNCTION simple RETURN varchar2 IS
    BEGIN
    RETURN ‘my_column’;
    END simple;
    --- Select
    SELECT simple FROM my_table;
    This does not work. It seems that output from function is passed in quotation i.e.
    SELECT ‘my_column’ FROM my_table;
    So the output from SELECT is a list of rows populated with values my_table:
    COLUMN     simple
    ROW1     my_column
    ROW2     my_column
    ROW3     my_column
    Can please someone help me with this?

    I'm not sure I got you right.
    In standard SQL everything must be known at compile time. If not dynamic SQL is required, but is a costly operation (usually requires parsing before each execution) so it should better not be used when standard SQL can do it.
    I provided a design time example where a function returns the column name from the given the table name and column id for a varchar2 column data type to make things simple. Then a query string is constructed and executed dynymically to return all column values of the chosen table_name.column_name.
    SELECT simple FROM my_tableAt compile time the simple function return value is unknown (any varchar2 value would do) you already find out you get the (same) return value (i.e column name) for each table row => dynamic SQL needed to get the column values
    The purpose of function would be to rename all columns for provided table.The table name would be provided, right? If yes => dynamic SQL
    What is the function supposed to return the column name (where would the new name come from?), the column alias (which table column would be renamed to the new name?)
    The user could use the new_column name as the column alias name submitting the query.
    Is it possible to do this?Maybe () using a pipelined function (different data types - number,date, ... not cosidered yet) but your simple query;
    <tt>SELECT simple FROM my_table</tt>
    might look like:
    <tt>select my_column_value new_column_name from table(get_column_value(table_name,column_name))</tt>
    Sorry, no Database at hand to provide a specific example.
    Regards
    Etbin

  • Select statement in a function does Full Table Scan

    All,
    I have been coding a stored procedure that writes 38K rows in less than a minute. If I add another column which requires call to a package and 4 functions within that package, it runs for about 4 hours. I have confirmed that due to problems in one of the functions, the code does full table scans. The package and all of its functions were written by other contractors who have been long gone.
    Please note that case_number_in (VARCHAR2) and effective_date_in (DATE) are parameters sent to the problem function and I have verified through TOAD’s debugger that their values are correct.
    Table named ps2_benefit_register has over 40 million rows but case_number is an index for that table.
    Table named ps1_case_fs has more than 20 million rows but also uses case_number as an index.
    Select #1 – causes full table scan runs and writes 38K rows in a couple of hours.
    {case}
    SELECT max(a2.application_date)
    INTO l_app_date
    FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
    WHERE a2.case_number = case_number_in and
    a1.case_number = a2.case_number and
    a2.application_date <= effective_date_in and
    a1.DOCUMENT_TYPE = 'F';
    {case}
    Select #2 – runs – hard coding values makes the code to write the same 38K rows in a few minutes.
    {case}
    SELECT max(a2.application_date)
    INTO l_app_date
    FROM dwfssd.ps2_benefit_register a1, dwfssd.ps2_case_fs a2
    WHERE a2.case_number = 'A006438' and
    a1.case_number = a2.case_number and
    a2.application_date <= '01-Apr-2009' and
    a1.DOCUMENT_TYPE = 'F';
    {case}
    Why using the values in the passed parameter in the first select statement causes full table scan?
    Thank you for your help,
    Seyed
    Edited by: user11117178 on Jul 30, 2009 6:22 AM
    Edited by: user11117178 on Jul 30, 2009 6:23 AM
    Edited by: user11117178 on Jul 30, 2009 6:24 AM

    Hello Dan,
    Thank you for your input. The function is not determinsitic, therefore, I am providing you with the explain plan. By version number, if you are refering to the Database version, we are running 10g.
    PLAN_TABLE_OUTPUT
    Plan hash value: 2132048964
    | Id  | Operation                     | Name                    | Rows  | Bytes | Cost (%CPU)| Time     | Pstart| Pstop |
    |   0 | SELECT STATEMENT              |                         |   324K|    33M|  3138   (5)| 00:00:38 |       |       |
    |*  1 |  HASH JOIN                    |                         |   324K|    33M|  3138   (5)| 00:00:38 |       |       |
    |   2 |   BITMAP CONVERSION TO ROWIDS |                         |     3 |     9 |     1   (0)| 00:00:01 |       |       |
    |*  3 |    BITMAP INDEX FAST FULL SCAN| IDX_PS2_ACTION_TYPES    |       |       |            |          |       |       |
    |   4 |   PARTITION RANGE ITERATOR    |                         |   866K|    87M|  3121   (4)| 00:00:38 |   154 |   158 |
    |   5 |    TABLE ACCESS FULL          | PS2_FS_TRANSACTION_FACT |   866K|    87M|  3121   (4)| 00:00:38 |   154 |   158 |
    Predicate Information (identified by operation id):
       1 - access("AL1"."ACTION_TYPE_ID"="AL2"."ACTION_TYPE_ID")
       3 - filter("AL2"."ACTION_TYPE"='1' OR "AL2"."ACTION_TYPE"='2' OR "AL2"."ACTION_TYPE"='S')
    Thank you very much,
    Seyed                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       

Maybe you are looking for