Howto replace Permanent "Temp" table?
Hi,
I'm joining a project, but I am too novice on PL/SQL. One particular Procedure does a search query. The approach can be summarized as:
* Build a SQL string base on values passed in the list of parameters
* Truncate a permanent table named Temp_SearchID
* Execute the dynamic SQL string which will populate the Temp_SearchID table (INSERT INTO Temp_SearchID SELECT ...)
* Populate the returned cursor by a SELECT joining other tables with the IDs in Temp_SearchID
{color:#ff0000}*Q1.*{color} If the application load increases, there will be a higher concurrency and let assume that there are several simultaneous calls to the procedure above. What would happen as all these calls has different parameters and they all want to compete to use the Temp_SearchID table their own way?
*{color:#ff0000}Q2.{color}* If the approach using a permanent Temp_SearchID table is not recommended, it is possible to dump the IDs in a cursor which is local only to the procedure. Then make a SELECT joining with this cursor? In the SQL Server world, this is possible using Table variable or session local temp tables. If it is possible to achieve this with PL/SQL, can you please show me the syntax or point me to some code snippets?
Thank you very much for any help.
CarbonFiber wrote:
In the scenario I am dealing with, the business rules are a little bit complex. Writing the entire SQL query in a string would indeed solve the problem. But it would be come hard to debug & test as the entire query now appear as a big string. I might ressort to that. As I am used to SQL Server, I would like to know if Oracle has a memory based structure, then join it with other tables to produce the final results. I don't know PL/SQL well enough to write a query joining a cursor with a table. Can you show me the PL/SQL syntax to do that?
From a performance perspective in Oracle the single, plain SQL approach probably would be the best, depending on some other factors, like e.g. how sharable the SQL generated would then be (or are you going to generate then literally thousands of different large SQL statement as part of your process).
As already discussed here you have in Oracle the option to create a GLOBAL TEMPORARY TABLE that holds data visible only to the session that's using it, but it's still writing/reading that data potentially from disk.
The subquery factoring approach outlined by David might also be a quite good option if statement complexity is your main issue.
The in-memory approach in Oracle is a bit more complex. You would need to create an type, a collection type on top of that and then use the PL/SQL collection to use in the query, e.g. like that:
create or replace type t_qualified_id as object (
productid integer
create or replace type t_qualified_id_array as table of t_qualified_id;
create or replace procedure test_collection as
in_memory_table t_qualified_id_array;
begin
select t_qualified_id(object_id)
bulk collect into in_memory_table
from user_objects;
for rec in (select object_id
from table(in_memory_table) a
inner join user_objects b
on a.productid = b.object_id) loop
null;
end loop;
end;
/or like that if you don't want to use the "object" type, you can just create an array of the built-in number/integer type.
create or replace type t_qualified_id_array as table of integer;
create or replace procedure test_collection as
in_memory_table t_qualified_id_array;
begin
select object_id
bulk collect into in_memory_table
from user_objects;
for rec in (select object_id
from table(in_memory_table) a
inner join user_objects b
on value(a) = b.object_id) loop
null;
end loop;
end;
/But you can see that there are subtle differences and you need to study the SQL and PL/SQL developer guide to get the details. It gets even more confusing because you can have in Oracle PL/SQL collection types and SQL collection types which differ in various aspects in terms of usage.
Regards,
Randolf
Oracle related stuff blog:
http://oracle-randolf.blogspot.com/
SQLTools++ for Oracle (Open source Oracle GUI for Windows):
http://www.sqltools-plusplus.org:7676/
http://sourceforge.net/projects/sqlt-pp/
Edited by: Randolf Geist on Sep 22, 2008 6:57 PM
Subquery factoring mentioned
Similar Messages
-
Global Temp Table or Permanent Temp Tables
I have been doing research for a few weeks and trying to comfirm theories with bench tests concerning which is more performant... GTTs or permanent temp tables. I was curious as to what others felt on this topic.
I used FOR loops to test out the performance on inserting and at times with high number of rows the permanent temp table seemed to be much faster than the GTTs; contrary to many white papers and case studies that have read that GTTs are much faster.
All I did was FOR loops which iterated INSERT/VALUES up to 10 million records. And for 10 mil records, the permanent temp table was over 500k milliseconds faster...
Anyone have an useful tips or info that can help me determine which will be best in certain cases? The tables will be used for staging for ETL Batch processing into a Data Warehouse. Rows within my fact and detail tables can reach to the millions before being moved to archives. Thanks so much in advance.
-Tim> Do you have any specific experiences you would like to share?
I use both - GTTs and plain normal tables. The problem dictates the tools. :-)
I do have an exception though that does not use GTTs and still support "restartability".
I need to to continuously roll up (aggregate) data. Raw data collected for an hour gets aggregated into an hourly partition. Hourly partitions gets rolled up into a daily partition. Several billion rows are processed like this monthly.
The eventual method I've implemented is a cross between materialised views and GTTs. Instead of dropping or truncating the source partition and running an insert to repopulate it with the latest aggregated data, I wrote an API that allows you to give it the name of the destination table, the name of the partition to "refresh", and a SQL (that does the aggregation - kind of like the select part of a MV).
It creates a brand new staging table using a CTAS, inspects the partitioned table, slaps the same indexes on the staging table, and then performs a partition exchange to replace the stale contents of the partition with that of the freshly build staging table.
No expensive delete. No truncate that results in an empty and query-useless partition for several minutes while the data is refreshed.
And any number of these partition refreshes can run in parallel.
Why not use a GTT? Because they cannot be used in a partition exchange. And the cost of writing data into a GTT has to be weighed against the cost of using that data by writing it (or some of it) into permanent tables. Ideally one wants to plough through a data set once.
Oracle has a fairly rich feature set - and these can be employed in all kinds of ways to get the job done. -
Global Temp table with BLOB causing session crash
Hi,
i have a table as follows:
create global temporary table spg_file_import (
name varchar2 (128) constraint sfi_nam_ck not null,
mime_type varchar2 (128),
doc_size number,
dad_charset varchar2 (128),
last_updated date,
content_type varchar2 (128),
content long raw,
blob_content blob
on commit delete rows
this is my 9ias 'document' table thats used to receive uploaded files which i modified to be global temporary.
what i want to do is:
a)upload a text file (xml)
b) convert that file to clob
c) store that file in new permanent table as clob
d) commit (hence delete temp table rows as they are no longer necessary)
to test it i have:
CREATE OR REPLACE procedure daz_html
as
begin
htp.p(' <FORM enctype="multipart/form-data" action="daz_fu" method="POST">');
htp.p(' <p>');
htp.p(' File to upload: <INPUT type="file" name="p_file_in"><br>');
htp.p(' <p><INPUT type="submit">');
htp.p(' </form>');
htp.p('</body>');
htp.p('</html>');
end;
CREATE OR REPLACE procedure daz_fu (
p_file_in varchar2
as
-- BLOB Stream locator
v_raw blob;
v_clob clob;
v_blob_length number;
v_length number;
v_buffer varchar2(32767);
v_pos number := 1;
begin
-- Get xml document from transient 9iAs data store.
select blob_content
into v_raw
from spg_file_import
where name = p_file_in;
-- create temp LOB
dbms_lob.createtemporary(v_clob, false);
-- get BLOB length
v_blob_length := dbms_lob.getlength(v_raw);
loop
-- get length to read. this is set as a max length of 32767
v_length := least((v_blob_length - (v_pos-1)),32767);
-- assign BLOB to a varchar2 buffer in preparation to convert to CLOB
v_buffer := utl_raw.cast_to_varchar2(dbms_lob.substr(v_raw, v_length, v_pos));
-- now write out to the CLOB
dbms_lob.writeappend(v_clob, v_length, v_buffer);
-- increment our position.
v_pos := v_pos + v_length;
-- exit when we are done.
exit when v_pos >= v_blob_length;
end loop;
commit;
htp.p('commit done!');
end;
now if i upload a small text file (about 5kb) it works with no problem.
however if I upload a large text file (say about 1Mb) it crashes oracle with:
Fri, 26 Jul 2002 11:49:24 GMT
ORA-03113: end-of-file on communication channel
DAD name: spgd1
PROCEDURE : daz_fu
USER : spg
URL : http://www.bracknell.bt.co.uk/pls/spgd1/daz_fu
PARAMETERS :
============
p_file_in:
F22210/Document.txt
this produces a large trc file.. the trace file indicates the crash occured on the commit; line
Current RBA:[0x4eb0.117.10]
*** 2002-07-26 12:35:11.857
ksedmp: internal or fatal error
ORA-00600: internal error code, arguments: [kcblibr_user_found], [4294967295], [2], [12583564], [65], [], [], []
Current SQL statement for this session:
declare
rc__ number;
begin
owa.init_cgi_env(:n__,:nm__,:v__);
htp.HTBUF_LEN := 255;
null;
daz_fu(p_ref_in=>:p_ref_in,p_type_in=>:p_type_in,p_file_in=>:p_file_in);
if (wpg_docload.is_file_download) then
rc__ := 1;
wpg_docload.get_download_file(:doc_info);
null;
commit;
else
rc__ := 0; null;
commit;
owa.get_page(:data__,:ndata__);
end if;
:rc__ := rc__;
end;
----- PL/SQL Call Stack -----
object line object
handle number name
812b1998 42 procedure SPG.DAZ_FU
819dff90 7 anonymous block
----- Call Stack Trace -----
If i reaplce the temporary table with a non-temp table of the same structure i get no problems what-so-ever. Am I doing something that I shouldnt be with global temporary tables?
Thanks.This is on Oracle 8.1.7.2
-
Global temp table trigger error on Oracle AS
we have a set of triggers that load a temp table in the before delete,update and process the table in an after statement trigger. the data that's loaded is a complaintid and when the complaintid is selected into a variable in the after statement, a No data found error is fired. This only happens on Oracle AS both 9i and 10g, it does not happen on jboss. All the app servers use connection pooling and they are 9i Enterprise Edition Dedicated database servers.
Is it possible that there is a bug in Oracle AS that allows multiple sessions to affect the same global variables ?
Sorry it's a long one, but I wanted to include everything I could
table creation script.
CREATE GLOBAL TEMPORARY TABLE TEMPEVENTS
( COMPLAINTID VARCHAR2(20) NOT NULL ENABLE,
COMPLAINTEVENTID NUMBER NOT NULL ENABLE,
STARTDATE DATE,
EVENTTYPE NUMBER,
EVENTSUBTYPE NUMBER,
DELETED NUMBER
) ON COMMIT DELETE ROWS
Before update trigger-- as a test I saved the data in a permanent table and all columns have usable values.
create or replace trigger BeforeUpdateReportDataROW
BEFORE Delete or Update of deleted, startdate on complaintevents
FOR EACH ROW
BEGIN
IF (DELETING AND :old.deleted = 0) OR (UPDATING AND :new.deleted=1 AND :old.startDate = :new.startDate) THEN
TEMPDATA.v_triggerType := 'D';
ELSIF UPDATING AND :old.deleted=1 AND :old.startDate = :new.startDate THEN /*undeleting*/
TEMPDATA.v_triggerType := 'U';
ELSIF UPDATING AND :old.startDate != :new.startDate THEN /*new date*/
TEMPDATA.v_triggerType := 'S';
ELSE
TEMPDATA.v_triggerType := 'N';
END IF;
TEMPDATA.v_NumEntries := TEMPDATA.v_NumEntries + 1;
TEMPDATA.v_complaintids(TEMPDATA.v_NumEntries) := :old.complaintid;
TEMPDATA.v_complainteventids(TEMPDATA.v_NumEntries) := :old.complainteventid;
END;
After statement trigger -- the error happens on the
SELECT complaintid
INTO complaintid
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index)
AND complainteventid = tempdata.v_complainteventids (loop_index);
statement. this is all one transaction the complaintid is loaded from the complaintevent table, and is not a primary key, nor is there only one record in the complaintevent table for each complaintid.
create or replace trigger complaintevents_del_upd_trig
AFTER DELETE OR UPDATE OF deleted, startdate
ON complaintevents
DECLARE
complaintid VARCHAR2 (20);
loop_index NUMBER;
hold_complaintid VARCHAR2 (20);
BEGIN
IF tempdata.v_triggertype = 'D'
THEN /*deleting event*/
hold_complaintid := ' ';
FOR loop_index IN 1 .. tempdata.v_numentries
LOOP
SELECT complaintid
INTO complaintid
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index)
AND complainteventid = tempdata.v_complainteventids (loop_index);
IF hold_complaintid != complaintid
THEN
INSERT INTO tempevents
(complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted)
SELECT complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index);
END IF;
DELETE tempevents
WHERE complainteventid =
tempdata.v_complainteventids (loop_index)
OR deleted = 1;
hold_complaintid := complaintid;
END LOOP;
ELSIF tempdata.v_triggertype = 'U'
THEN /*undeleting*/
hold_complaintid := ' ';
FOR loop_index IN 1 .. tempdata.v_numentries
LOOP
SELECT complaintid
INTO complaintid
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index)
AND complainteventid = tempdata.v_complainteventids (loop_index);
IF hold_complaintid != complaintid
THEN
INSERT INTO tempevents
(complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted)
SELECT complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index);
END IF;
DELETE tempevents
WHERE deleted = 1;
INSERT INTO tempevents
(complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted)
SELECT complaintid, complainteventid, startdate, eventtype,
eventsubtype, 0
FROM complaintevents
WHERE complainteventid =
tempdata.v_complainteventids (loop_index);
hold_complaintid := complaintid;
END LOOP;
ELSIF tempdata.v_triggertype = 'S'
THEN /*date change*/
hold_complaintid := ' ';
FOR loop_index IN 1 .. tempdata.v_numentries
LOOP
SELECT complaintid
INTO complaintid
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index)
AND complainteventid = tempdata.v_complainteventids (loop_index);
IF hold_complaintid != complaintid
THEN
INSERT INTO tempevents
(complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted)
SELECT complaintid, complainteventid, startdate, eventtype,
eventsubtype, deleted
FROM complaintevents
WHERE complaintid = tempdata.v_complaintids (loop_index);
END IF;
DELETE tempevents
WHERE deleted = 1;
hold_complaintid := complaintid;
END LOOP;
ELSE
RETURN;
END IF;
END;CREATE GLOBAL TEMPORARY TABLE test_glb ON COMMIT DELETE ROWS
AS SELECT * FROM test1;btw I'm assuming you are just using the SELECT statement to copy the definition of test1. Since DDL statements commit, there will be no rows in test_glb after creating it.
Edited by: William Robertson on Feb 23, 2009 7:31 AM -
Global Temp Table, always return zero records
I call the procedure which uses glbal temp Table, after executing the Proc which populates the Global temp table, i then run select query retrieve the result, but it alway return zero record. I am using transaction in order to avoid deletion of records in global temp table.
whereas if i do the same thing in SQL navigator, it works
Cn.ConnectionString = Constr
Cn.Open()
If FGC Is Nothing Then
Multiple = True
'Search by desc
'packaging.pkg_msds.processavfg(null, ActiveInActive, BrandCode, Desc, Itemtype)
SQL = "BEGIN packaging.pkg_msds.processavfg(null,'" & _
ActiveInActive & "','" & _
BrandCode & "','" & _
Desc & "','" & _
Itemtype & "'); end;"
'Here it will return multiple FGC
'need to combine them
Else
'search by FGC
SQL = "BEGIN packaging.pkg_msds.processavfg('" & FGC & "','" & _
ActiveInActive & "','" & _
BrandCode & "',null,null); end;"
'will alway return one FGC
End If
' SQL = " DECLARE BEGIN rguo.pkg_msds.processAvedaFG('" & FGC & "'); end;"
Stepp = 1
Cmd.Connection = Cn
Cmd.CommandType = Data.CommandType.Text
Cmd.CommandText = SQL
Dim Trans As System.Data.OracleClient.OracleTransaction
Trans = Cn.BeginTransaction()
Cmd.Transaction = Trans
Dim Cnt As Integer
Cnt = Cmd.ExecuteNonQuery
'SQL = "SELECT rguo.pkg_msds.getPDSFGMass FROM dual"
SQL = "select * from packaging.aveda_mass_XML"
Cmd.CommandType = Data.CommandType.Text
Cmd.CommandText = SQL
Adp.SelectCommand = Cmd
Stepp = 2
Adp.Fill(Ds)
If Ds.Tables(0).Rows.Count = 0 Then
blError = True
BlComposeXml = True
Throw New Exception("No Record found for FGC(Finished Good Code=)" & FGC)
End If
'First Row, First Column contains Data as XML
Stepp = 0
Trans.Commit()Hi,
This forum is for Oracle's Data Provider and you're using Microsoft's, but I was curious so I went ahead and tried it. It works fine for me. Here's the complete code I used, could you point out what are you doing differently?
Cheers,
Greg
create global temporary table abc_tab(col1 varchar2(10));
create or replace procedure ins_abc_tab(v1 varchar2) as
begin
insert into abc_tab values(v1);
end;
using System;
using System.Data;
using System.Data.OracleClient;
class Program
static void Main(string[] args)
OracleConnection con = new OracleConnection("data source=orcl;user id=scott;password=tiger");
con.Open();
OracleTransaction txn = con.BeginTransaction();
OracleCommand cmd = new OracleCommand("begin ins_abc_tab('foo');end;", con);
cmd.Transaction = txn;
cmd.ExecuteNonQuery();
cmd.CommandText = "select * from abc_tab";
OracleDataAdapter da = new OracleDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
Console.WriteLine("rows found: {0}", ds.Tables[0].Rows.Count);
// commit, cleanup, etc ommitted for clarity
} -
Global Temp Table Not found - SSIS
I am facing below error while using global temp table in SSIS.
[OLE DB Destination [78]] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E37.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80040E37 Description: "Table/view either does not exist or contains errors.".
[OLE DB Destination [78]] Error: Failed to open a fastload rowset for " ##AGENTDTLS". Check that the object exists in the database.
[SSIS.Pipeline] Error: component "OLE DB Destination" (78) failed the pre-execute phase and returned error code 0xC0202040.
1) For data connection manager - Retain same connection is set to True
2) Data Flow task - Delay Validation is set to True
3) Destination Task - Using Temp Table - ValidateExternalMetadata is set to false.
4) I am just using one data connection.
5) before using the temp file I am checking if its exits and if yes drp it first and create it.
Not able to understand the reason for failure.Why don't you use permanent table in tempdb?
Kalman Toth Database & OLAP Architect
SQL Server 2014 Design & Programming
New Book / Kindle: Exam 70-461 Bootcamp: Querying Microsoft SQL Server 2012 -
can anyone please explain me the differnce of having a view replaced with a temp table.
the reason i am asking is one of our jobs takes 4 hours to complete using a view, if the same view is replaced by a table, it just takes 20 minutes. If the base tables are being modified, will the results be the same for both , ie using a view vs a temp table in place of a view..pls help..thnks in advnace.
NikiP.S. If the view is indexed (materialized) all bets are off!
This is not true, and SQL Server does not work in the manner that other products like Oracle would in this aspect. Indexed Views are updated as the data changes in the tables as a part of the transaction changing the information. This is why there are limitations and criteria that govern what kinds of views can be indexed or not (ie, no self joins).
Jonathan Kehayias
http://sqlblog.com/blogs/jonathan_kehayias/
http://www.sqlclr.net/
Please click the Mark as Answer button if a post solves your problem! -
How do I CREATE IF NOT EXISTS Temp table in PLSQL?
hello, how do I CREATE IF NOT EXISTS Temp table in PLSQL? The following table is to be created in FIRST call inside a recursive function (which you'll see in QUESTION 2).
QUESTION 1:
CREATE GLOBAL TEMPORARY TABLE TmpHierarchyMap
Id numeric(19,0) NOT NULL,
ParentId numeric(19,0) NOT NULL,
ChildId numeric(19,0) NOT NULL,
... more ...
) on commit delete rows');
QUESTION 2: How to return a temp table from a function?
For example, this is how I'm doing it at the moment, using Nested Table.
EXECUTE IMMEDIATE 'CREATE OR REPLACE TYPE TmpHierarchyMapObjType AS OBJECT
Id numeric(19,0) ,
ParentId numeric(19,0),
ChildId numeric(19,0),
... more ...
EXECUTE IMMEDIATE 'CREATE OR REPLACE TYPE TmpHierarchyMapTableType AS TABLE OF TmpHierarchyMapObjType;';
CREATE OR REPLACE FUNCTION fnGetParentsTable
ObjectId number,
ObjectClassifier varchar2
RETURN TmpHierarchyMapTableType
IS
TmpHierarchyMap TmpHierarchyMapTableType := TmpHierarchyMapTableType();
ThisTempId varchar2(32);
CURSOR spGetParents_cursor IS
SELECT
Id,
ParentId,
ChildId,
FROM TMP_HIERARCHYMAP
WHERE TempId = ThisTempId;
BEGIN
SELECT sys_guid() INTO ThisTempId FROM dual;
spRecursiveGetParents(ObjectId, ObjectClassifier, ThisTempId);
FOR oMap in spGetParents_cursor LOOP
TmpHierarchyMap.Extend();
TmpHierarchyMap(TmpHierarchyMap.Count) := TmpHierarchyMapObjType( oMap.Id
, oMap.ParentId
, oMap.ChildId
END LOOP;
DELETE FROM TMP_HIERARCHYMAP WHERE TempId = ThisTempId;
RETURN TmpHierarchyMap;
END fnGetParentsTable;
QUESTION 3: what does the word GLOBAL means? I read that temp table is visible only to a particular database connection/session and will be dropped automatically on termination of the session. i can only find this information in some forum discussion but failed to locate this in Oracle doc, can someone point me in right direction please?
Many thanks!
REF:
http://stackoverflow.com/questions/221822/sybase-developer-asks-how-to-create-a-temporary-table-in-oracle
http://www.oracle-base.com/articles/8i/TemporaryTables.phpdevvvy wrote:
so if I CREATE GLOBAL TEMPORARY TABLE twice on second pass of my recursive function what then...?You don't create it inside your function.
You create the GTT once on your database outside of the function and then just leave it there and use it.
Tables should not be dynamically created and dropped.
Only other database engines such as SQL Server use the concept of creating temporary tables during the execution of code. Oracle uses a "create once, use whenever" methodology. -
Does Oracle support #temp tables like SQL Server 7? And if it does, then how? Thank you very much in advance.
For Oracle8i and above, you could use something like the following:
drop type Humans
create or replace type Human is Object (
Name VARCHAR2(50),
Age NUMBER(3)) ;
show errors
create or replace TYPE Humans is TABLE of Human ;
show errors
set serveroutput on
declare
tbl Humans ;
cnt number ;
begin
tbl := Humans(NULL) ;
tbl(1) := Human('First', 39) ;
tbl.Extend ;
tbl(2) := Human('Second', 55) ;
select count(*) into cnt from TABLE(CAST(tbl AS Humans)) ;
dbms_output.put_line('Total rows in Humans table:'||cnt) ;
end ; -
Urgent! Slow Result Set -- temp table slowing me??
-- Running BC4J/JHeadstart/UIX
Description:
I have a uix page that calls a Servlet and passes a TABLE_NAME. The Servlet gets the TABLE_NAME and calls a class that extends oracle.jheadstart.persistence.bc4j.handler.DataSourceHandlerImpl to create a ViewObject and get the data we need. Once the ViewObject is passed back to the servlet, the servlet loops through the VIewObject and builds a report. See the problem below and the code at the bottom.
Problem:
I am running a query that returns approx 5000 records to my ViewObject. I then loop through the rows and construct a report. The view object will return the first 1085 records quickly, however, the following 4000 come back very slowly. I read online that BC4J creates temp tables to store large resultsets and then streams the data to the user as you need it. Is this our potential bottleneck?
Questions:
Is there a way to have it return all the rows? What can I do to speed this up?
Code:
--- Begin Servlet Snippet ---
private ByteArrayOutputStream createReport(HttpServletRequest request)
try{
// PARM_REPORT = table name
String reportName = request.getParameter(PARM_REPORT);
System.out.println(">> calling getReport for " + reportName);
RdmUserHandlerImpl handler = new RdmUserHandlerImpl();
ViewObject vo = handler.getReportView2(reportName, request.getSession().getId());
System.out.println(">> back from get report");
// loop through report and print every 100
while(vo.hasNext())
curRow++;
if (curRow % 100 == 0 )
System.out.println(curRow + "");
--- End Servlet Snippet ---
--- Begin RdmUserHandlerImpl Snippet ---
public ViewObject getReportView2(String tableName, Object sessionId) throws Exception {
System.out.println("IN GET REPORT VIEW");
ApplicationModule appMod = (ApplicationModule)getConnection("classpath...resource.MyUser", sessionId);
// First see if we already created the view definition
ViewObject vo = appMod.findViewObject(tableName);
// If it was already created then refresh it, else lets try to create it
if(vo != null) {
System.out.println("found existing view");
vo.reset();
else {
System.out.println("view not found, making new view");
String query="SELECT * FROM " + tableName;
System.out.println("QUERY = " + query);
vo = appMod.createViewObjectFromQueryStmt(tableName, query);
// max fetch returns -1
System.out.println("MAX Fetch Size = " + vo.getMaxFetchSize());
return vo;
--- End RdmUserHandlerImpl Snippet ---
Please reply asap! Deadline is coming fast!
-MattMatt,
I think that you are right, the temporary tables created by BC4J are the reason for making it slow after a certain number of records. One of Steve Muench's articles includes the text:
One of the most frequent performance-related questions we get on the Oracle Technet discussion forum is a question like, "After I query about a 1000 rows in a view object, my application gets very, very slow. What's happening?"
It explains how you can turn off this feature, see the full article at http://www.oracle.com/technology/products/jdev/tips/muench/voperftips/index.html.
The following article gives a lot of helpful information about the temporary tables:
http://www.oracle.com/technology/products/jdev/htdocs/bc4j/bc4j_temp_tables.html
The next article gives general tips for performance tuning of BC4J:
http://www.oracle.com/technology/products/jdev/howtos/10g/adfbc_perf_and_tuning.html
Hope this helps,
Sandra Muller
JHeadstart Team -
How to work on temp table in oracle 10g
Hi Guys,
I have one simple procedure and it is returning some records through dbms_output.put_line.
cursor c1 is select object_name from t_Turbo;
type c1_type is table of c1%rowtype;
rec1 c1_type;
begin
open c1;
loop
fetch c1 bulk collect into rec1 limit 200;
for i in 1..rec1.count loop
dbms_output.put_line(rec1.i);
end loop;
exit when c1%notfound;
end loop;
end;
Now i am plaing to use temp table at dmbs_output.put_line in place and from there I want to select the records.
Can any one help me on this.
Thanks in advance!
Regards,
KLRThis is what you need.
create or replace procedure test ( pRet out sys_refcursor )
as
begin
open pRet for select object_name from t_Turbo;
end;SYS_REFCURSOR is a cursor type defined by oracle. You can define your owner. -
Usage of Temp tables in SSIS 2012
Hello,
We have many SSIS packages (2008 R2) which imports data to a temp table and process it from there.
We are upgrading to SQL server 2012 and facing the issue with temp table as working table and our ssis packages fail in 2012. While investigating found that SQL Server 2012 deprecates FMTONLY option
and instead uses
sp_describe_first_result_set , which does not support using of temp tables as import table. SSIS works fine in our workstations but not in the DEV box. With SQL 2012, I can execute from my workstation, which has (11.0.2100.60) where as DEV server
has SQL Server version 11.0.3000.0
Also when I ran profile with that of the DEV box, it gives two different statements
from workstation (11.0.2100.60)
CREATE TABLE #temp (
Id varchar(255) NULL,
Name varchar(255) NULL )
go
declare @p1 int
set @p1=NULL
declare @p3 int
set @p3=229378
declare @p4 int
set @p4=294916
declare @p5 int
set @p5=NULL
exec sp_cursoropen @p1 output,N'select * from #temp',@p3 output,@p4 output,@p5 output
select @p1, @p3, @p4, @p5
go
it works fine
But with the DEV server (version 11.0.3000.0), it executes the below sql and it fails to get the meta data
CREATE TABLE #temp (
Id varchar(255) NULL,
Name varchar(255) NULL )
exec [sys].sp_describe_first_result_set N'select * from [dbo].[#temp]'
On checking the assembly difference between the versions, I could only see Microsoft.SqlServer.ManagedDTS.dll being 11.0.3000.0, which I replace by 11.0.2100.60 version. but still getting the same result.
The other different I found is with ,Net framework libraries.
Could you advise whats the assembly causing this issue between our workstation and DEV server i.e 11.0.2100.60 and 11.0.3000.0
Many thanksScripts are taken from profiler.
The error message is
The metadata could not be determined because statement 'Select * from #branchscan' uses a temp table.
I could see the work around saying use of table variable and global temp tables. We are having around 100+ ssis packages which uses temp table for loading the data from a flat file and respective SP to process the data from the temp table. above
error is thrown during the pre-execute phase of the OLE db Destination, when trying to get the meta data of the table.
At this stage, it would be difficult for us to change the logic to global temp or TVP
Thanks -
Stored procedure with temp table creation inside and using it
I want to create a temp table inside a stred procedure and make use of it . I want perform some delete statements based on select statemets .An I want to drop the table at the end .
When I tried to create a table inside the stored procedure using exxecute immediate statement ,.
sql_stmt := 'CREATE GLOBAL TEMPORARY TABLE pattern_str_temp as select * from pattern_structure';
EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE pattern_str_temp as select * from woc_pattern_structure' ;
Then my select statements that contain this table do not identify the table name.
I got compilor error when I use it in hte stored procedure in the select statement .Then I did like this-
WHENEVER SQLERROR CONTINUE
DROP TABLE pattern_str_temp;
CREATE TABLE pattern_str_temp AS SELECT * FROM pattern_structure ;
COMMIT;
CREATE OR REPLACE PACKAGE BODY Woc_Delete_Model_Data
AS
NAME: Woc_Delete_Model_Data
PURPOSE:
REVISIONS:
Ver Date Author Description
1.0 11/01/2008 gtutika 1. Deletes given Product Model
PROCEDURE deleteCategory(p_product_model IN varchar2,
p_request_status OUT VARCHAR2,
p_err_mesg OUT VARCHAR2
IS
l_category VARCHAR2(200);
l_count NUMBER;
CURSOR getAttribute IS
SELECT Category_Name
FROM
Woc_Attribute_Category
WHERE Attribute_Name in
(SELECT Child_Name FROM pattern_structure
WHERE Child_Type = 'Attribute' and product_Model_Name = p_product_model)
FOR UPDATE;
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
--dbms_output.put_line('START-Inside DeleteCategory Procedure .........');
--sql_stmt := 'CREATE GLOBAL TEMPORARY TABLE pattern_str_temp as select * from pattern_structure';
--EXECUTE IMMEDIATE 'CREATE GLOBAL TEMPORARY TABLE pattern_str_temp as select * from pattern_structure' ;
OPEN getAttribute ;
LOOP
FETCH getAttribute INTO l_category ;
EXIT WHEN getAttribute%NOTFOUND;
l_count := Is_Category_Used(p_product_model , l_category);
IF (l_count=0) THEN
DELETE FROM WOC_ATTRIBUTE_CATEGORY where CATEGORY_NAME = l_category;
DELETE from woc_item_category
where CATEGORY_NAME = l_category;
DELETE FROM WOC_CATEGORY WHERE CATEGORY_NAME = l_category;
END IF;
END LOOP;
--(getAttribute%ROWCOUNT);
CLOSE getAttribute;
--dbms_output.put_line('END-Inside DeleteCategory Procedure .........');
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
p_err_mesg := 'ERROR IN CUSOR';
--dbms_output.put_line('ERROR in CUSOR');
ROLLBACK;
END;
FUNCTION Is_Category_Used(p_product_model IN varchar2 , p_category IN Varchar2)
RETURN NUMBER IS
l_count NUMBER;
l_attribute VARCHAR2(40);
l_pattern varchar2(30);
CURSOR getAttribute IS
SELECT attribute_Name from
WOC_ATTRIBUTE_CATEGORY WHERE category_name = p_category and Attribute_Name in
(Select Child_Name from pattern_str_temp
where child_type = 'Attribute' and product_Model_Name = p_product_model);
BEGIN
DBMS_OUTPUT.ENABLE(1000000);
SELECT count(*) into l_count from
WOC_ATTRIBUTE_CATEGORY WHERE category_name = p_category and Attribute_Name in
(Select Child_Name from pattern_str_temp
where child_type = 'Attribute' and product_Model_Name <> p_product_model);
OPEN getAttribute;
LOOP
FETCH getAttribute INTO l_attribute;
EXIT WHEN getAttribute%NOTFOUND;
DELETE FROM pattern_str_temp WHERE Product_Model_Name=p_product_model
and child_type = 'Attribute' and child_Name= l_attribute;
END LOOP;
CLOSE getAttribute;
RETURN l_count;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
--dbms_output.put_line('ERROR in CUSOR');
ROLLBACK;
END;
PROCEDURE delete_batch_woc_model(p_product_model IN VARCHAR2,p_flag IN VARCHAR2,
p_err_mesg OUT VARCHAR2)
IS
p_request_status VARCHAR2(30);
BEGIN
deleteCategory(p_product_model,p_request_status ,p_err_mesg );
EXCEPTION WHEN OTHERS THEN
dbms_output.put_line(SQLERRM);
p_err_mesg := 'ERROR IN CUSOR';
dbms_output.put_line('ERROR in CUSOR');
ROLLBACK;
END;
END Woc_Delete_Model_Data;
--drop table pattern_str_temp ;
SHOW ERRORS;
But once the data is deleted , the data in the temp table is deleted when I load the data and try to delete it agian since I have no data in temp table ,the data is not deleted .So I need to create the temp table every time the stored procedure is called ,delete accordingly and drop the table at the end .
Please suggest how to do it.
Thanks.I'm not sure I understand what you're attempting to do...
What is the benefit of a temporary table that stores the same set of data that is in the master table? Why not just
DELETE FROM child_table1
WHERE foreign_key IN (
SELECT primary_key
FROM master_table
WHERE some_condition);
DELETE FROM child_table2
WHERE foreign_key IN (
SELECT primary_key
FROM master_table
WHERE some_condition);
DELETE FROM child_table30
WHERE foreign_key IN (
SELECT primary_key
FROM master_table
WHERE some_condition);
DELETE FROM master_table
WHERE some_condition;or
FOR x IN (SELECT * FROM master_table WHERE some_condition)
LOOP
DELETE FROM child_table1 WHERE foreign_key = x.primary_key;
DELETE FROM child_table2 WHERE foreign_key = x.primary_key;
DELETE FROM child_table30 WHERE foreign_key = x.primary_key;
DELETE FROM master_table WHERE primary_key = x.primary_key;
END LOOP;Justin -
Varrays/Nested tables/temp tables
Within my PL/SQL code, which I eventually will turn into stored procedure, I want to use Varrays, or Nested tables, or temp tables, whatever is the most suitable.
Right now I am using dbms_output.put_line() just to display list of 1 column values. Further, I need to use this list in Where ... In (my list ) of other query.
Prior to Oracle, I worked with SQL Server and I have always used temp table in such situations. But in Oracle it does not seem like good solution.
Could please someone explain me what object should I use in this situation, and what's more important, code examples how to assign values to it, and how to apply Select against this object.
Thanks.create or replace type ttab_object_type is table of varchar2(18);
show errors
declare
type ttab_object_name is table of user_objects.object_name%type index by binary_integer;
tab_object_name ttab_object_name;
tab_object_type ttab_object_type;
begin
tab_object_type := ttab_object_type('TABLE', 'INDEX');
select object_name
bulk collect into tab_object_name
from user_objects
where object_type in (select * from table(tab_object_type));
for i in 1.. tab_object_name.count loop
dbms_output.put_line(tab_object_name(i));
end loop;
end;
Richard -
hello
*okay this following is WORKING and CORRECT:*
CREATE OR REPLACE FUNCTION fnGetParents
ObjectId number,
ObjectClassifier varchar2
RETURN typescursorType
IS
fnGetParents_cursor types.cursorType;
BEGIN
EXECUTE IMMEDIATE (''CREATE GLOBAL TEMPORARY TABLE TMP_HierarchyMap
Id numeric(19,0) NOT NULL,
ParentId numeric(19,0) NOT NULL,
ChildId numeric(19,0) NOT NULL,
) on commit delete rows'');
EXECUTE IMMEDIATE (''CREATE GLOBAL TEMPORARY TABLE TEMP_ID
Id numeric(19,0) NOT NULL,
bDone NUMERIC(1,0) NOT NULL
) on commit delete rows'');
/* recursive call: spRecursiveGetParents(ObjectId, ObjectClassifier); */
OPEN fnGetParents_cursor FOR
SELECT
Id,
ParentId,
ChildId,
FROM TMP_HierarchyMap;
RETURN fnGetParents_cursor;
END fnGetParents;
My question is, how can I do something like this:
EXECUTE IMMEDIATE 'CREATE OR REPLACE TYPE TmpHierarchyMapObjType AS OBJECT
Id numeric(19,0) ,
ParentId numeric(19,0),
ChildId numeric(19,0),
EXECUTE IMMEDIATE 'CREATE OR REPLACE TYPE TmpHierarchyMapTableType AS TABLE OF TmpHierarchyMapObjType;';
EXECUTE IMMEDIATE 'CREATE OR REPLACE PACKAGE types AS
TYPE cursorType IS REF CURSOR;
END; ';
CREATE OR REPLACE FUNCTION fnGetParents
ObjectId number,
ObjectClassifier varchar2
RETURN typescursorType
IS
TmpHierarchyMap TmpHierarchyMapTableType := TmpHierarchyMapTableType();
fnGetParents_cursor types.cursorType;
BEGIN
EXECUTE IMMEDIATE (''CREATE GLOBAL TEMPORARY TABLE TMP_HierarchyMap
Id numeric(19,0) NOT NULL,
ParentId numeric(19,0) NOT NULL,
ChildId numeric(19,0) NOT NULL,
) on commit delete rows'');
EXECUTE IMMEDIATE (''CREATE GLOBAL TEMPORARY TABLE TEMP_ID
Id numeric(19,0) NOT NULL,
bDone NUMERIC(1,0) NOT NULL
) on commit delete rows'');
/* recursive call: spRecursiveGetParents(ObjectId, ObjectClassifier); */
OPEN fnGetParents_cursor FOR
SELECT
Id,
ParentId,
ChildId,
FROM TMP_HierarchyMap;
-- I want to learn how to enumerate a temp table and put it in a nested table but keep getting error on loop
FOR oMap in spGetChildren_cursor LOOP
TmpHierarchyMap.Extend();
TmpHierarchyMap(TmpHierarchyMap.Count) := TmpHierarchyMapObjType( oMap.Id ,oMap.ParentId , oMap.ChildId
END LOOP;
RETURN fnGetParents_cursor;
END fnGetParents;
I just want to know how for sake of learning.
ThanksAs mentioned yesterday, if you create database objects dynamically, you have to query them dynamically.
For example, you could use the DBMS_SQL package, which offers one of the most flexible ways of dyanamic queries..
[DBMS_SQL Package|http://download.oracle.com/docs/cd/B19306_01/appdev.102/b14258/d_sql.htm#sthref6136]
CREATE OR REPLACE PROCEDURE run_query(p_sql IN VARCHAR2) IS
v_finaltxt VARCHAR2(4000);
v_v_val VARCHAR2(4000);
v_n_val NUMBER;
v_d_val DATE;
v_ret NUMBER;
c NUMBER;
d NUMBER;
col_cnt INTEGER;
f BOOLEAN;
rec_tab DBMS_SQL.DESC_TAB;
col_num NUMBER;
BEGIN
c := DBMS_SQL.OPEN_CURSOR;
DBMS_SQL.PARSE(c, p_sql, DBMS_SQL.NATIVE);
d := DBMS_SQL.EXECUTE(c);
DBMS_SQL.DESCRIBE_COLUMNS(c, col_cnt, rec_tab);
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
WHEN 2 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_n_val);
WHEN 12 THEN DBMS_SQL.DEFINE_COLUMN(c,j,v_d_val);
ELSE
DBMS_SQL.DEFINE_COLUMN(c,j,v_v_val,2000);
END CASE;
END LOOP;
FOR j in 1..col_cnt
LOOP
v_finaltxt := ltrim(v_finaltxt||','||lower(rec_tab(j).col_name),',');
END LOOP;
DBMS_OUTPUT.PUT_LINE(v_finaltxt);
LOOP
v_ret := DBMS_SQL.FETCH_ROWS(c);
EXIT WHEN v_ret = 0;
v_finaltxt := NULL;
FOR j in 1..col_cnt
LOOP
CASE rec_tab(j).col_type
WHEN 1 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_v_val);
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
WHEN 2 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_n_val);
v_finaltxt := ltrim(v_finaltxt||','||v_n_val,',');
WHEN 12 THEN DBMS_SQL.COLUMN_VALUE(c,j,v_d_val);
v_finaltxt := ltrim(v_finaltxt||','||to_char(v_d_val,'DD/MM/YYYY HH24:MI:SS'),',');
ELSE
v_finaltxt := ltrim(v_finaltxt||',"'||v_v_val||'"',',');
END CASE;
END LOOP;
DBMS_OUTPUT.PUT_LINE(v_finaltxt);
END LOOP;
DBMS_SQL.CLOSE_CURSOR(c);
END;
SQL> exec run_query('select * from emp');
empno,ename,job,mgr,hiredate,sal,comm,deptno
7369,"SMITH","CLERK",7902,17/12/1980 00:00:00,800,,20
7499,"ALLEN","SALESMAN",7698,20/02/1981 00:00:00,1600,300,30
7521,"WARD","SALESMAN",7698,22/02/1981 00:00:00,1250,500,30
7566,"JONES","MANAGER",7839,02/04/1981 00:00:00,2975,,20
7654,"MARTIN","SALESMAN",7698,28/09/1981 00:00:00,1250,1400,30
7698,"BLAKE","MANAGER",7839,01/05/1981 00:00:00,2850,,30
7782,"CLARK","MANAGER",7839,09/06/1981 00:00:00,2450,,10
7788,"SCOTT","ANALYST",7566,19/04/1987 00:00:00,3000,,20
7839,"KING","PRESIDENT",,17/11/1981 00:00:00,5000,,10
7844,"TURNER","SALESMAN",7698,08/09/1981 00:00:00,1500,0,30
7876,"ADAMS","CLERK",7788,23/05/1987 00:00:00,1100,,20
7900,"JAMES","CLERK",7698,03/12/1981 00:00:00,950,,30
7902,"FORD","ANALYST",7566,03/12/1981 00:00:00,3000,,20
7934,"MILLER","CLERK",7782,23/01/1982 00:00:00,1300,,10
PL/SQL procedure successfully completed.
SQL> exec run_query('select * from dept');
deptno,dname,loc
10,"ACCOUNTING","NEW YORK"
20,"RESEARCH","DALLAS"
30,"SALES","CHICAGO"
40,"OPERATIONS","BOSTON"
PL/SQL procedure successfully completed.Or you could build up a query to use with execute immediate, but then you will need to ensure you know what columns you expect as output.
Maybe you are looking for
-
OK... I've read several threads, and there doesn't seem to an answer out there... The other night while updating my Nano (the second day I had it) it disappeared from the source list and hasn't reappeared. About half of my MP3s updated to it before i
-
Page Publishing Correctly in Safari but Not in Firefox!
Hello! Question: When I publish my page, it looks exactly like it should in Safari but not in Firefox! Why is this and how can I correct this? Thank you!
-
I trouble with listeners on a movieclip. does anybody can help me?
I have been working with this for two days and i cant make it work.......I am going crazy.... Ok i have this code if someone can help... i will appreciate that A LOT. The thing is if i compile the program everything works well, if i upload it or test
-
Waiting for monitor enty messages in thread dump
Hi, I've a thread dump of a container in a Oracle Application Server 9.0.4.1 (running 1.4.2_07) right before restart because off low memory and a lot of threads in this dump are in this state: "AJPRequestHandler-ApplicationServerThread-1588" prio=1 t
-
After upgrading to ff 9.* i've lost my app tabs and tab groups.
Had a problem with FF "not responding" when I was trying to upgrade to 9.* - The only way around it was to start a new session, which apparently wiped out all the tab groups I had set, along with the app tabs I had set. Now when I start FF I just get