Appropriate use of temporary table - or can pivot approach be used?

I am relatively new to pl/sql. My problem is that I need to return one row of data (joining several tables, including a 1-many), but with a varying number of columns (from single values returned from the 1-many table), and record types cannot be dynamically defined or modified (such as with adding columns).
I am not sure if pivoting the many table would work, because the range of values returned (albeit not expected to realistically exceed a dozen) do not fall within a small set.
Would dynamically generating SQL to create a temporary table with the requisite number of columns be the best approach? Then I could select all the data into the table, iterate through the results from the 1-many and populate into the columns, and then select * from the temp table for the return resultset.
Specifics: There is a document table which has a 1-many table containing the CC's for that document. Only one row will ever be returned from the master doc table, and 0-n rows from the CC table. There could be no CC's for the doc, or there could be any number. I need to be able to return all the columns from the document table PLUS the CC's as if they were all one row in a table.
So example of a return row might be a doc with n # of cc's
DOC_ID | DOC_TYPE | DOC_OWNER | <etc> | CC_1 | CC_2 | ... | CC_n
or a doc with all its fields and no cc's
DOC_ID | DOC_TYPE | DOC_OWNER | <etc>
So I am thinking the pl/sql would have to
1. declare the SQL statement to create a temporary table
2. declare the SQL statement to insert data into the temporary table
3. declare the SQL statement to query data from the temporary table
4. fetch the count of CC's based on doc id from the CC table
5. use that count to loop and
1. append columns onto the sql that creates the temporary table
2. append columns onto the sql that will query the temporary table
6. query the CC's table and read the values into an array
7. use the count again to loop and dynamically create the insert statement for the temporary table, using the values from step 6
8. execute the insert statement
9. query the temporary table using the sql generated in step 5.2 and return that rowset
HUGE thanks to anyone who can provide input on this. I know it's not a new problem, I am just unsure of the best approach to the solution.

It's not that I require a single SQL statement to do this; in fact I expected to have to execute at least 2 in the procedure to accomplish the goal. The problem I am running into is that I need to return a dynamic number of columns, based on the number of entries in the 1-many table.
I'm guessing if I can look up the number of rows in the 1-many table that I need to pivot before I actually do the pivot, I will be able to use this technique?
The reasoning for all this can be summed up in one word: legacy. The row is being sent back to a legacy component which only takes that one single row of data. Currently, we are only limited to 3 CC entries and are expanding the system to allow >3, hence the 1-many table. However, the legacy component isn't able to handle anything more complex than that one row. Our clients will be able to change their definitions easily to expand from CC1, CC2, CC3 to however many they want to use. However, changing to multiple rows wouldn't be an option because it would incur too much complexity.

Similar Messages

  • Using temporary tables with a ref. cursor

    I want to use a temporary table to populate certain data and then return a ref cursor fetching data from the temporary table.
    1. Will this approach work ?
    2. Do I need to drop the temporary table ? Can I drop the table as a last statement in the stored proc (remember a ref cursor based on this table is to be returned as a out parameter).
    Please help.

    1. Will this approach work ?Sort of, just like it is possible to dig a trench with a spoon. It can be done, but why can't you just write a select that returns the data without storing intermediate versions of your processing somewhere.
    2. Do I need to drop the temporary table ?No. and you shouldn't.
    Can I drop the table as a last statement in the stored proc
    (remember a ref cursor based on this table is to be returned as a out parameter).No.
    If you really need to use a temporary table, it should be created one time when the application is installed, and should never be created in code.

  • Creating temporary table in pl/sql block problem

    hello
    i have a problem in creating and using temporary table in pl/sql block
    please verify below block
    begin
    execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
    insert into alitemp1 (co_t,color) values ('001','red');
    execute immediate 'DROP TABLE alitemp1';
    end;
    when i execute that block i will receive this error
    insert into alitemp1 (co_t,color) values ('001','red');
    ERROR at line 3:
    ORA-06550: line 3, column 14:
    PL/SQL: ORA-00942: table or view does not exist
    ORA-06550: line 3, column 2:
    PL/SQL: SQL Statement ignored
    i think it because that alitemp1 table don't create
    but two below block run fine
    begin
    execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
    execute immediate 'DROP TABLE alitemp1';
    end;
    begin
    execute immediate 'create global temporary table alitemp1 (co_t varchar2(10),color varchar2(10))';
    end;
    select table_name from user_tables where table_name='ALITEMP1';
    TABLE_NAME
    ALITEMP1
    it means that problem is when the below line exists in block
    insert into alitemp1 (co_t,color) values ('001','red');
    if may please guide me

    In addition to the comments by Justin and 3360, you cannot do what you want the way you are doing it.
    All objects referred to in a PL/SQL block must exist at the time the block is compiled. In your case, since it is an anonomous block, that is run time. Since you are dynamically creating the temporary table you need to refer to it dynamically as well. More like:
    BEGIN
    EXECUTE IMMEDIATE 'create global temporary table alitemp1 (co_t varchar2(10),
                                                               color varchar2(10))';
    EXECUTE IMMEDIATE 'insert into alitemp1 (co_t,color) values (:b1,:b2)' USING '001', 'red';
    EXECUTE IMMEDIATE 'DROP TABLE alitemp1';
    END;However, don't do that it is a really bad idea. Just create the temporary table, if you really need it, once and use it in your processing.
    In most cases, things that SQL Server needs temporary tables for can be done easily in Oracle with a single SQL statement,
    John

  • Oracle temporary tables

    Hi ,
    we have a application for transfering data approx 1 million records from one schema to another. the data is first inserted into a table temporarily and after all the data is transfered the data is manually deleted from this table.
    we are planning to replace this table with Oracle Temporary table. Can you please let us know if this would increase the performance and why???
    Thanks & Regards
    Saroj

    In theory it should, but you won't know whether the difference is going to be noticeable until you try.
    Oracle has to do much less work with global temporary tables. It knows no other sessions will be using the data so it does not need to bother with rollback segments or locks. It also does not bother with redo because there will not be a need to recover.

  • Can I use Parallel execution for Global Temporary table within SP and How

    Dear Gurus,
    I have Global temporary table as below
    Create global temporary table Temp_Emp
    empno number,
    ename varchar2(20),
    deptno number
    ) on commit preserve rows;
    During processing I insert the data into this table and then fire query on Temp_Emp, get the data and pass it to front end.
    The SP as shown below
    Create or replace procedure get_emp_data
    empid in number,
    emp_detail out RefCsr -- Ref cursor
    as
    begin
    -- some code here
    open emp_detail for
    select *
    from Temp_Emp
    where empno = empid;
    end get_emp_data;
    Can use Parallel Query execution on Temp_Emp table and how ?
    i.e. do need to explicitly use parallel construct in query or is it default.
    Because I have many SQL like above (on global temporary tables) within Stored Procedures.
    Can anybody give me any suggestion.
    Thanking in Advance
    Sanjeev

    How come you are populating a temporary table and then opening a cursor on this temporary table for the front end to use?
    Couldn't you presumably just form a query out of the code you use to populate the temporary table? This is the recommended approach in Oracle.

  • Can oracle temporary tables be used with distributed transactions?

    Hello,
    Does anybody know if temporary tables are supported with distributed transactions?
    We use a temporary table to store query results and see no problems when the JDBC driver (Type 2 or Type 4) is used with local transactions. The temporary tables are set for transaction-level data persistence (delete rows on commit).
    When we switch to JDBC/XA driver we occasionally get ORA-14450 error (java.sql.SQLException: ORA-14450: attempt to access a transactional temp table already in use).
    Many thanks...

    I have been able to use temporary tables on remote databases, so I don't think that it is forbidden. Of course, I'm not using JDBC so that might be a problem.
    The other thing that occurs to me is that you are doing something other than DML with the table e.g. trying to drop it. If that is the case you should re-read the documentation and remind yourself of the purpose of temporary tables.
    Cheers, APC

  • How to Use Temporary table on report builder

    Hi community!
    Well, i'm trying to build a temporary table based report in Oracle Report Builder. in "After Parameter Form Trigger" I've placed a stored procedure that populate a temporary table and I've based my report on it. The problem is Report shows no data. When i execute this procedure directly on database and i perform a select on my temporary table, it show all inserted data.
    I hope somebody can to help me because I tried many ways to build this report with my temporary table and always looks blank.

    Temporary tables are session specific.
    If particular session is closed then no data will be found on your temporary table in an another session.
    My suggestion is, on "After parameter form" trigger you directly populate the GTT without using procedure.
    Hope this will help.

  • How to use Temporary Table in PL-SQL

    In MySQL there is no Temporary table concept.
    So for intermediate calculation I have created a table as below
    create table SequenceTempTable
    SessionId VARCHAR(50),
    Sequence VARCHAR(500),
    CreatedDate DATE
    ) ENGINE=MEMORY;
    Whenever I invoke a SP, I load the data into SequenceTempTable using Session Id as below
    CREATE PROCEDURE `GetSequence`(
    IN Start_Date VARCHAR(25),
    IN End_Date VARCHAR(25)
    BEGIN
    SELECT UUID() INTO v_SessionId;
    INSERT INTO SequenceTempTable values (v_SessionId,'1,2,5,3',now());
    required code
    DELETE FROM SequenceTempTable WHERE SessionId = v_SessionId;
    COMMIT;
    END;
    i.e. I have created a table as temporary table (created once),
    and load the data using Session Id and once session specific intermediate computation done,
    I deleted the session specific data.
    Could you give me examples of How to use Temporary table in PL-SQL code with respect to my above example.
    Because I have gone through creating Temporary table but I stuck with use in PL-SQL. I mean to say Is there any need of creating table in advance before invoking SP.
    And one more thing as in MySQL temp table I created which is using MEMORY engine i.e. this table will always be in MEMORY so there is no need of writing data on disk.
    Regards
    Sanjeev

    Hi Sanjeev
    Read about GTT here
    http://www.oracle-base.com/articles/8i/TemporaryTables.php
    GTT always contains just session specific data. \
    In case you want to use the GTT in the same session again you can use option
    ON COMMIT PRESERVE ROWS;
    Or if it is used just once in the session use can use
    ON COMMIT DELETE ROWS;
    Do remember that for GTT the data of one session can not be accessed in other session.
    Also you can go away with Delete from GTT if not used again in same session.
    Regards
    Arun

  • How can I implement the equivilent of a temporary table with "on commit delete rows"?

    hi,
    I have triggers on several tables. During a transaction, I need to gather information from all of them, and once one of the triggers has all the information, it creates some data. I Can't rely on the order of the triggers.
    In Oracle and DB2, I'm using temporary tables with "ON COMMIT DELETE ROWS" to gather the information - They fit perfectly to the situation since I don't want any information to be passed between different transactions.
    In SQL Server, there are local temporary tables and global.  Local temp tables don't work for me since apparently they get deleted at the end of the trigger. Global tables keep the data between transactions.
    I could use global tables and add some field that identifies the transaction, and in each access to these tables join by this field, but didn't find how to get some unique identifier for the transaction. @@SPID is the session, and sys.dm_tran_current_transaction
    is not accessible by the user I'm supposed to work with.
    Also with global tables, I can't just wipe data when "operation is done" since at the triggers level I cannot identify when the operation was done, transaction was committed and no other triggers are expected to fire.
    Any idea which construct I could use to acheive the above - passing information between different triggers in the same transaction, while keeping the data visible to the current transaction?
    (I saw similar questions but didn't see an adequate answer, sorry if posting something that was already asked).
    Thanks!

    This is the scenario: If changes (CRUD) happen to both TableA and TableB, then log some info to TableC. Logic looks something like this:
    Create Trigger TableA_C After Insert on TableA {
      If info in temp tables available from TableB
            Write info to TableC
       else
           Write to temp tables info from TableA
    Create Trigger TableB_C After Insert on TableB {
      If info in temp tables available from TableA
            Write info to TableC
       else
           Write to temp tables info from TableB
    So each trigger needs info from the other table, and once everything is available, info to TableC is written. Info is only from the current transaction.
    Order of the triggers is not defined. Also there's no gurantee that both triggers would fire - changes can happen only to TableA / B and in that case I don't want to write anything to TableC.
    The part that gets and sets info to temp table is implemented as temp tables with "on commit delete rows" in DB2 / Oracle.
    What do you think? As I've mentioned, I could use global temp tables with a field that would identify the transaction, but didn't find something like that in SQL Server. And, the lifespan of local temp tables is too short.

  • Query hint to force SQL to use a temporary table in a CTE query?

    Hi,
    is it possible to tell SQL Server to create a temporary table by itself when I'm using a CTE in my query?
    I have a query starting with a CTE where I group by my record, then another recursive CTE use the first CTE and finally my select statement like:
    with cte as (select a,b,c,row_number() ...  from mytable group by a,b,c)
    , cte2(select .... from cte A where rownum =1
    union all select ... from cte B inner join cte2 C on ......
    select * from cte2
    this query is very very slow, but if I store the first CTE into a temporary table and then cte2 consume my temp table rather than the CTE, the query is very fast.
    creating the temp table took 10sec and the select took 20sec
    while the initial query didnt return anything  after 2minutes!!!
    so what can I try to do to have the query running in less than 30sec without creating the temp table first?
    is there a query hint which can be used to tell SQL Server to convert the CTE into a temp table?
    as I have a lot of query to manage, I want to simplify my model without relying in temporary tables every time I suffer this issue...
    thanks.

    What is your SQL Server version?
    There is no hint to materialize results of cte into a temp table, so the solution you tried is the best you can have.
    I think the idea of materializing CTE into a temp table was already proposed on Connect. Try searching for this and vote.
    For every expert, there is an equal and opposite expert. - Becker's Law
    My blog
    My TechNet articles

  • How can i write the trigger for Global Temporary Table

    Hi Grus,
    How can i write the trigger for Global Temporary Table.
    I was created the GTT with trigger using the below script .
    CREATE GLOBAL TEMPORARY TABLE GLOBAL_TEMP
    EMP_C_NAME VARCHAR2(20 BYTE)
    ON COMMIT PRESERVE ROWS;
    CREATE OR REPLACE TRIGGER TRI_GLOBAL_TEMP
    BEFORE DELETE OR UPDATE OR INSERT
    ON GLOBAL_TEMP
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
    INSERT INTO EMPNAME VALUES (:OLD.EMP_C_NAME);
    END;
    trigger was create successfully, but the wouldn't insert into to EMPNAME Table..
    Please guide whether am correct or not? if not kindly give a correct syntax with example
    Thanks in Advance,
    Arun M M

    BEGIN
    INSERT INTO EMPNAME VALUES (:OLD.EMP_C_NAME);
    END;
    you are referencing old value in insert stmt.
    BEGIN
    INSERT INTO EMPNAME VALUES (:new.EMP_C_NAME);
    END;then run ur application it works fine...
    CREATE GLOBAL TEMPORARY TABLE GLOBAL_TEMP
    EMP_C_NAME VARCHAR2(20 BYTE)
    ON COMMIT PRESERVE ROWS;
    CREATE OR REPLACE TRIGGER TRI_GLOBAL_TEMP
    BEFORE DELETE OR UPDATE OR INSERT
    ON GLOBAL_TEMP
    REFERENCING NEW AS NEW OLD AS OLD
    FOR EACH ROW
    BEGIN
    dbms_output.put_line(:OLD.EMP_C_NAME||'yahoo');
    INSERT INTO EMPNAME VALUES (:new.EMP_C_NAME);
    dbms_output.put_line(:OLD.EMP_C_NAME);
    END;
    create table EMPNAME as select * from GLOBAL_TEMP where 1=2
    insert into GLOBAL_TEMP values('fgfdgd');
    commit;
    select * from GLOBAL_TEMP;
    select * from EMPNAME;
    output:
    1 rows inserted
    commit succeeded.
    EMP_C_NAME          
    fgfdgd              
    1 rows selected
    EMP_C_NAME          
    fgfdgd              
    1 rows selectedgot it Arun
    Edited by: OraclePLSQL on Dec 28, 2010 6:07 PM

  • CREATE TEMPORARY TABLE USING EXECUTE IMMEDIATE

    Hi All,
    i have a question,
    how can i create a temporary table using EXECUTE IMMEDIATE ??
    Like:
    CREATE GLOBAL TEMPORARY table new_table as (Select * from old_table);
    Thanks,
    Edited by: xDeviates on Jun 11, 2012 3:13 PM

    It looks like you are approaching the problem incorrectly. As I suggested in Dynamic Select, it sounds like you, at most, want a function that returns a SYS_REFCURSOR (it's still not obvious to me why you would even want/ need to resort to dynamic SQL in the first place)
    CREATE OR REPLACE FUNCTION get_dynamic_cursor( p_table_name IN VARCHAR2 )
      RETURN sys_refcursor
    IS
      l_rc sys_refcursor;
    BEGIN
      OPEN l_rc FOR 'SELECT * FROM ' || dbms_assert.sql_object_name( p_table_name );
      RETURN l_rc;
    END;which you can then call from your application
    SQL> variable rc refcursor;
    SQL> exec :rc := get_dynamic_cursor( 'EMP' );
    PL/SQL procedure successfully completed.
    SQL> print rc
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7369 SMITH      CLERK           7902 17-DEC-80        801
            20
          7499 ALLEN      SALESMAN        7698 20-FEB-81       1601        300
            30
          7521 WARD       SALESMAN        7698 22-FEB-81       1251        500
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7566 JONES      MANAGER         7839 02-APR-81       2976
            20
          7654 MARTIN     SALESMAN        7698 28-SEP-81       1251       1400
            30
          7698 BLAKE      MANAGER         7839 01-MAY-81       2851
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7782 CLARK      MANAGER         7839 09-JUN-81       2451
            10
          7788 SCOTT      ANALYST         7566 19-APR-87       3001
            20
          7839 KING       PRESIDENT            17-NOV-81       5001
            10
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7844 TURNER     SALESMAN        7698 08-SEP-81       1501          0
            30
          7876 ADAMS      CLERK           7788 23-MAY-87       1101
            20
          7900 JAMES      CLERK           7698 03-DEC-81        951
            30
         EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM
        DEPTNO
          7902 FORD       ANALYST         7566 03-DEC-81       3001
            20
          7934 MILLER     CLERK           7782 23-JAN-82       1301
            10
    14 rows selected.Justin

  • Using Global Temporary Table in OBIEE 11

    Hi,
    THe requirement is to run a database function before the report runs. This Function accepts 5 parameters (Presentation Variable) and populates a GTT Global Temporary Table.
    This GTT is configured in presentation Layer.
    Issue:
    1. Created a dummy report which returns only one row and called the fucntion using "Evaluate" in this.
    2. Created 2nd report using GTT Columns.
    All these 2 reports placed on dashboard and Presentation variable are set in the prompt. The first one runs correctly and populate the "Regular Table". Means when I create a regular table instead of GTT I can see the correct record. But if I change it to GTT then the data does not get populated in this table.
    Any Inputs?
    Regards

    HI,
    If you are using a GTT, you need to run the function which populates the GTT before OBI server executes the select query on that table.
    In your case, the OBI server is executing the select query from the table before the data is populated in the table.
    In order to force the BI server to run the query after the GTT is populated, you need to specify the condition in the connection pool settings under the connection scripts tab.
    In the execute before query, enter your physical query which runs the function to populate the GTT.
    Hope this helps !
    Thanks,
    Vineeth

  • Using Temporary Table in SSIS

    I have a dataflow task which puts the result in a temporary table. I want to put the table result in a flat file but is not able to do that. Can anyone help?
    Here is the sql code
    use adventureworks2008r2
    declare @totalcount as float
    declare @addcount as float
    declare @citycount as float
    declare @addperct as float
    declare @cityperct as float
    declare @temp table (name varchar (40), percentage float)
    set @totalcount = (select count(*)from person.Address)
    set @addcount = (select COUNT (*)from person.Address where AddressLine2 = null)
    set @citycount = (select COUNT (*) from person.Address where City is not null )
    set @addperct = 100*(@addcount/@totalcount)
    set @cityperct = 100*(@citycount/@totalcount)
    insert into @temp
    select 'Addressline2',ROUND (@addperct,2)
    insert into @temp
    select 'City',ROUND (@CITYPERCT,2)
    SELECT * FROM @temp

    What you're using is table variable and not temporary table. It will be out of scope outside batch so you cant use it anywhere after code.
    I think if you want to use it in further tasks you should use temporary tables (# tables) after setting RetainSameConnection property to true.
    See
    http://consultingblogs.emc.com/jamiethomson/archive/2006/11/19/SSIS_3A00_-Using-temporary-tables.aspx
    Please Mark This As Answer if it helps to solve the issue Visakh ---------------------------- http://visakhm.blogspot.com/ https://www.facebook.com/VmBlogs

  • Best to use in terms of tuning Global Temporary table or PLSQL Table type

    Hi All,
    which one is best to use in terms of tuning Global Temporary table or PLSQL table type?
    Thanks in Advance.
    Regards
    Deepika

    user8828028 wrote:
    which one is best to use in terms of tuning Global Temporary table or PLSQL table type?The answer to which one is better depends on the requirements - and an informed decision as to which one to use to address those requirements.
    Thus it is important to understand how these work. They are nothing alike.
    PL/SQL collections reside in the PGA. Can only be used in SQL via binding. Cannot be indexed. Temp tables on the other hand does not use expensive PGA. Does not need to be bind in SQL. Can be indexed. Etc.
    Sure, a (surgical) saw and scalpel are both used on the operating table - but for very different purposes.

Maybe you are looking for