![]() |
Oracle & Dyn Cursor & Bulk SQL
Moin :hi:
Gegeben sei folgendes Problem: (bitte nicht über den tieferen Sinn von Code oder Bennenungen grübeln -> sind nur Beispiele ;) ) In mehreren Usern gibt es mehrere Tabellen, die die Spalten a, b & c enthalten. Diese 3 Spalten möchte ich so schnell wie möglich in PL/SQL-Tabellen einlessen -> bulk collect. AABEER... Die Tabellen/User heißen natürlich nicht gleich. :( Ich habe eben die 3 möglichen Varianten ausprobiert, die mir eingefallen sind (bisher konnte ich die Kombi Bulk SQL & dyn. SQL gut umschiffen ;) )
Wozu der Thread? Ich hoffe jemand von euch wird mir gleich sagen "Mensch, warum machst du das denn so! Das geht doch ... viel einfacher." :zwinker: Achso: Das ganze muss leider kompatibel ab Ora 8.174 sein :? |
Re: Oracle & Dyn Cursor & Bulk SQL
Hi Robert,
nicht wirklich kürzer und auch schlecht optimierbar für den Server (gilt aber für dynamic SQL allgemein), aber in MSSQL sähe es so aus - weis nicht, ob Du das in Ora nachbauen kannst:
SQL-Code:
Gruß aus Berlin
--Beispieltabellen:
CREATE TABLE DeineSysTabelle ( FeldName varchar(255) , TabellenName varchar(255)) INSERT INTO DeineSysTabelle (FeldName, TabellenName) VALUES ('Vorname', 'Personen') INSERT INTO DeineSysTabelle (FeldName, TabellenName) VALUES ('Name' , 'Personen') CREATE TABLE DeineDatenTabelle( Vorname varchar(255) , Name varchar(255)) INSERT INTO DeineSysTabelle (Vorname, Name) VALUES ('Hans' , 'Wurst') INSERT INTO DeineSysTabelle (Vorname, Name) VALUES ('Peter', 'Pan' ) DECLARE @FELD varchar(255) , @TABELLE varchar(255) , @SQL nvarchar(4000) -- nimmt Statement für Cursordeklaration auf DECLARE @MeinDynCur Cursor -- dynamischer Cursor SET @SQL = 'SET @MeinDynCur = CURSOR FOR SELECT ' DECLARE MeinStatCur CURSOR FOR SELECT FeldName FROM DeineSysTabelle OPEN MeinStatCur FETCH NEXT FROM MeinStatCur INTO @FELD , @TABELLE WHILE @@Fetch_Status = 0 BEGIN -- durch Felder iterieren SET @SQL = @SQL+@FELD+', ' -- Feldliste ergänzen FETCH NEXT FROM MeinStatCur INTO @FELD , @TABELLE END -- WHILE SET @SQL = @SQL+' 0' -- PseudoFeld für letztes Komma SET @SQL = @SQL+' FROM '+@TABELLE SET @SQL = @SQL+' WHERE Bedingung' -- CursorStatement fertig EXEC sp_execustesql(@SQL) -- legt Cursor an OPEN @MeinDynCur -- öffnet ihn ... |
Re: Oracle & Dyn Cursor & Bulk SQL
Hi !
Wenn ich Deine Probleme richtig gedeute habe kann Dir sowas vielleicht helfen : create table neue_table as ((select a,b,c from table_a) union (select a,b,c from table_b) union (select a,b,c from table_c)) |
Re: Oracle & Dyn Cursor & Bulk SQL
Sorry ihr 2, ich habe mich wohl nicht genau genug ausgedrückt. :oops:
PL/SQL Tabelle <> DB Tabelle -> es ist eher so etwas wie eine Collection oder ein Array ;) Mein Problem ist die Kombi Bulk SELECT und dyn. Cursor. Würde ich auf das Bulk SELECT verzichten könnte ich es so machen:
SQL-Code:
Aber die ständigen Context switches zwischen PL/SQL und SQL würden wie eine angezogene Handbremse wirken.
create or replace procedure TestDynCurNoBulk
( pOwner in varchar2 ,pTable in varchar2 ) is -- constants Lf char(1) := Chr(10); -- cursors type WeakTypedDynCur is ref cursor; DynCur WeakTypedDynCur; -- Bulk tables type ShortChrTab is table of varchar2(20) index by binry_integer; a ShortChrTab; b ShortChrTab; c ShortChrTab; begin open DynCur for 'SELECT a' || Lf || ' ,b' || Lf || ' ,c' || Lf || 'FROM ' || pOwner || '.' || pTable; a(0) := null; b(0) := null; c(0) := null; loop fetch DynCur INTO a(a.Last + 1) ,b(b.Last + 1) ,c(c.Last + 1); EXIT When DynCur%NotFound; end loop; close DynCur; end; Per Bulk DML bekomme ich mehrere 100.000 Datensätze in t < 70 ms. Wenn ich durch den Cursor iteriere würde es mehr als 1 Sekunde dauern! Das Problem ist bei den ersten 2 Varianten im ersten Post, dass Oracle im voraus wissen muss, wie der Cursor "aussieht" um das Bulk SELECT vorbereiten zu können. Er schiebt dabei schließlich in einem Schritt die gesamte Abfrage in die 3 Collections. Ich fürchte ich muss mit der 3. Variante leben, auch wenn dabei ein kompletter Block kompiliert werden muss -> das kostet wieder min. 10ms :( |
Re: Oracle & Dyn Cursor & Bulk SQL
SpeedJunky!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:28 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz