Temporary Tables in Oracle 8i

5/14/99, Guy Bayes

Introduction

Most data base management systems, including Sybase, Informix, and MS SQL Server, have built-in constructs for the creation and management of temporary relation tables. Oracle 8i does not directly support these structures. This shortcoming can seriously complicate migration from the above systems to Oracle.

This paper is intended primarily to present, discuss, and evaluate ways of duplicating Sybase temporary tables in Oracle 8i. Four primary methods will be examined. The value of these methods will be judged on the following criteria:

We will evaluate these issues in the following fashion. First, we present the qualities of a Sybase temporary table which we attempting to duplicate. Then we will present four methods to simulate temporary tables in Oracle8i. We outline the general strategy, then describe the method in detail. The methods pros and cons will be evaluated using the above criteria. Whenever possible, code examples will be provided. Also, whenever possible, feasibility testing will have been executed using the code examples provided, the results of these tests will also be included. Finally, unresolved or answered research questions will be detailed.

The material in this document was based primarily on the following sources:

  1. Oracle 8i Developer's Guide:

  2. http://technet.oracle.com/doc/server.815/a68003/01_03sch.htm#7794
     

  3. Oracle Concepts Manual "Temporary Tables"

  4. http://technet.oracle.com/doc/server.815/a67781/c08schem.htm#16097
     

  5. Oracle Migration Workbench for Microsoft SQL Server Reference Guide

  6. http://technet.oracle.com/doc/workbench/C5.htm
     

  7. Data Warehousing and Materialized Views
          http://technet.oracle.com/doc/server.815/a67775/ch1.htm
 
 

Hyperlinks in this document link to online documentation on Oracle's Tech-Net web site at:

         http://technet.oracle.com ,

which requires a registered username and password. You may obtain a username and password by selecting the "Membership" link from the home page of the site.

Properties of Sybase Temporary Tables:

Sybase temporary tables have the following desirable properties we wish to duplicate in Oracle:

  1. Security: They can be created, on the fly, by any user query, without any Create Table, or other special privilege.
  2. Simplicity: They are managed by the system, and are automatically dropped when the session that created them ends.
  3. Functionality and Robustness: They avoid cross session naming conflict. Temp table names do not have to be unique inside a database, only inside a session. Two concurrent sessions in the same database can both create temporary tables with the same name and different schemas without any conflict arising.
  4. Transparency: They accomplish all these properties completely behind the scenes, without any participation by the developer.
Proposal I: Dynamically Creating Temporary Tables in Oracle

General Strategy:

Create a package of PL/SQL procedures which will do the following:

  1. Take as an argument the DDL string to create a temp table
  2. Parse this string, and extract relevant information
  3. Create in a temporary database the passed table name as
  4. TEMP_table_name_SESSIONID_TIMESTAMP
  5. Log the table and session id with the DB
  6. Create an alias for the user to the new table as the originally
  7. passed table name
  8. When the session that created the table terminates, drop it
This is similar to the process used to migrate from MS SQL to Oracle. Most of the code is already available, once you figure out what it does. This requires dynamic SQL, which is supported by the DBMS_SQL package provided with Oracle.

Pros:


Cons:

Example:

Example code for such a packet can be found at:

http://technet.oracle.com/doc/workbench/C5.htm#Definition of temp_table_catalog

Feasibility Testing:

The following code runs and seems to function correctly under Oracle 8.0.5.0.0 It dynamically creates tables mytable_xxxxxx with the session id appended

DECLARE

THIS_SESSION NUMBER;

TABLE_NAME varchar2(100) := 'mytable';

cid INTEGER;

BEGIN

    cid := DBMS_SQL.OPEN_CURSOR;

    THIS_SESSION := userenv ('sessionid');

    dbms_sql.parse(cid, 'CREATE TABLE '|| table_name || '_' || to_char(THIS_SESSION) || ' (salary int) ', dbms_sql.v7);

    DBMS_SQL.CLOSE_CURSOR(cid);

END;
 
 

Proposal II: Nesting in the From Clause

General Strategy:

Use Oracles extended SQL syntax to simulate temp tables by nesting in the FROM clause:

Explanation:

Oracle supports significant expansion on the standard syntax of SQL. One of these expansions is to allow nested subqueries in the "FROM" clause of SQL. These subqueries can be used to simulate nested tables as follows:

Example:

Say we have this process:

SELECT A.*, B.name, B.id

INTO #Temp1

FROM TableA A, TableB, b

WHERE condition1

go

SELECT C.*, D.name_code

INTO #Temp2

FROM #Temp1 C, TableD D

WHERE condition2

go

SELECT E.*, F.org_code

INTO FinalTable

FROM #Temp2 E, TableF F

WHERE condition3

go

In oracle SQL, we can simulate it as:

SELECT E.*, F.org_code

INTO FinalTable

FROM Tablef F, (SELECT C.*, D.name_code
                            FROM TableD D, (SELECT A.*, B.name, B.id
                                                            FROM TableA A, TableB B
                                                            WHERE condition1) C
                            WHERE condition2) E

WHERE condition3

Pros:


Cons:

Example:

SELECT *

INTO #TEMP1

FROM TableA

WHERE condition1

go

UPDATE #TEMP1

SET update

WHERE condition2

go

SELECT *

FROM #TEMP1

...

would be difficult to simulate. You would have to perform all the updates on the end result table. In some cases this would not be sufficient.

Feasibility Testing:

The following code runs and seems to function correctly under Oracle 8.0.5.0.0

SELECT count(*)
FROM (SELECT salary FROM DATA WHERE salary <500);

Proposal III:

General strategy:

Oracle 8i supposedly supports a "Global Temporary Table" syntax. While this is not the same as a Sybase temp table, it may be useful for our processes.

Explanation:

A Global Temp Table is not the same thing as a Sybase temp table. For all practical purposes, it is a globally defined table with rows associated with the session id's. Thus, each session can only see and interact with the rows it has created, and a truncate table will only drop those rows associated with the session id that called the truncate. Similarly, the table can only be dropped and recreated if no active sessions have rows currently in it.

In addition, Oracle will "clean up" the temp table, either after the transaction or session has completed, depending on how you create it. No memory leaks,

Thus, you don't have to worry about multiple instances of the same process using the same temp table, the sessionid will handle that.

The main difference in functionality is this:

Global Temp tables with the same name must have the exact same schema. There is only 1 table, really.

So, if we wanted to use this option, we would have to enforce a unique temp table naming scheme. As long as all script names are unique, we could simply prefix the temp table name with the script name.

Example:

For script ld_ldgr_entr_gt.sh, Sybase temp table #temp1 would have to be renamed:

CREATE GLOBAL TEMPORARY TABLE ld_ldgr_entr_gt_temp1 (

startdate DATE, enddate DATE, cost NUMBER)

ON COMMIT PRESERVE ROWS;

Pros:

Cons:
  Feasibility Testing:

Not done, not supported by current development platform (Oracle 8.0.3).

Research issues unresolved:

Proposal IV: Materialized Views:

General Strategy:

Avoid the need for temp tables by reworking how datagroups are created. Instead of creating denormilzied tables, use materialized views to provide the same type of data structure:

Explanation:

Up until now, we have been using datagroup builds to physically create denormalizied data tables. We've been doing this instead of using views because, in Sybase, views are computed dynamically, at query time, and thus are very inefficient for large amounts of data. Oracle supports a "materialized" view structure which precomputes and physically stores the joins needed to support a view.

Pros:

Cons: Example:

CREATE MATERIALIZED VIEW detail_fact_mv

PARALLEL

BUILD IMMEDIATE

REFRESH FORCE

AS

SELECT f.rowid "fact_rid", s.store_key, s.store_name, f.dollar_sales, f.unit_sales, f.time_key

FROM fact f, time t, store s

WHERE f.store_key = s.store_key(+) AND

                f.time_key = t.time_key(+);