2010-12-01 7 views
2

Ich brauche eine kleine gespeicherte Prozedur, um die folgende Logik auszuführen?Gespeicherte Prozedur zum Zurückgeben einer Liste von Sequenz-IDs

procedure_name (seq_name IN varchar2 (50), Block Zählung IN int, return_ids OUT)

Schleife von 1
return_ids zu Block Zählung: = wählen 'seq_name' || .NEXTVAL von dual;
Endschleife
return return_ids

Im Grunde, was ich eine gespeicherte Prozedur tun möchte, ist, die mich in einer Sequenz Namen übergeben können, wie viele IDs ich brauche und wieder zu mir die von IDs aufgelistet erzeugt, dass ich Verwenden Sie in JAVA. Der Grund, dies für mich zu tun, besteht darin, eine Liste von IDs zurückzugeben, die ich in JAVA verwenden kann, und niemand sonst verwendet diese Sequenz-IDs. Wo sie später in anderen Masseneinsätzen verwendet werden. Im Wesentlichen reservieren Sie einen Block von Sequenz-IDs.

Antwort

1

Ich wäre besorgt über die Logik, die erfordert IDs erzeugt werden, bevor Datensätze in die Datenbank eingefügt werden.

Alternativ können Sie in Erwägung ziehen, zuerst Zeilen einzufügen, die IDs aus den Zeilen auszuwählen und dann eine Aktualisierungsanweisung für die Massenoperation zu verwenden. Dies ist jedoch immer noch nicht so vorzuziehen, als dass der Java-Code nicht von ids abhängt, bis die tatsächliche Information bereit ist, eingefügt zu werden.

Sie können Ihre Informationen in XML (oder jedes andere Datenformat, das Ihre Datenbank verstehen kann) übertragen und dann eine gespeicherte Prozedur aufrufen, um die Masseneinfügungen auszuführen.

+0

Nun, wenn ich DBA-Unterstützung hätte, würde ich viel lieber einfach Arrays in eine Prozedur übergeben und sie alle Einfüge auf der DB-Seite behandeln lassen. Aber da ich nicht die Unterstützung habe ... – stuckAtWork

+0

Ich versuche, eine große Anzahl von Datensätzen in verwandten hierarchischen Tabellen einzufügen. Da ich IDs aus der Top-Level-Tabelle brauche, kann ich sie in die Second-Level-Tabelle einfügen und so weiter zur dritten und vierten Level-Tabelle und so weiter. Ich möchte auch nicht JDBC verwenden, um die DB zu rufen, um die ID jedes Mal zu erhalten, während ich einfüge. Ich möchte nur einen Block von SEQ_IDs holen, den ich mit verschiedenen Arrays füllen kann, damit ich dann die Arrays in Batch-Einfügungen verwenden kann. – stuckAtWork

+0

Ich bin verwirrt von Ihrem Kommentar über keine DBA-Unterstützung. Sie können eine gespeicherte Prozedur schreiben, um IDs zu reservieren, aber Sie können keine gespeicherte Prozedur schreiben, um die Einfügungen in jede Tabelle mit den richtigen IDs auszuführen. –

3

Hier ist eine Möglichkeit, ein Array aus der PL/SQL-Prozedur zurückzugeben.

Erstellen Sie eine Sammlung von Zahlen, initialisieren Sie sie in Ihrer Prozedur und füllen Sie sie mit Zahlen, um zurückzukehren. Zum Beispiel:

create or replace type narray as table of number; 

create or replace procedure get_seq_ids(seq_name in varchar2, 
    block_count in number, return_ids out narray) 
as 
begin 
    return_ids := narray(); 
    return_ids.extend(block_count); 
    for i in 1 .. block_count 
    loop 
     execute immediate 'select ' || seq_name || '.nextval from dual' 
      into return_ids(i); 
    end loop; 
end; 
/
+0

Danke vls, genau das habe ich gebraucht! – stuckAtWork

0

IMHO, das Beste, was Sie tun können, verweist nur sequence_name.nextval direkt in Ihrem INSERT INTO, in der VALUES Klausel.

Sie sagten, Sie möchten vermeiden, dass andere dieselben IDs verwenden. this site Referenzierung:

Die Sequenz (oder Oracle, was das betrifft) stellt sicher, dass keine andere Sitzung oder anderen Anruf NEXTVAL innerhalb der gleichen Sitzung die gleiche Anzahl aus der Sequenz bekommt.

So ist die Einzigartigkeit einer Sequenz 'Zahlen in Oracle garantiert.

+0

Das Problem ist für eine Anwendung, die DML-Operationen aus Performance-Gründen anordnen möchte, wobei der nextval-Aufruf im INSERT eine nachfolgende Abfrage zum Abrufen dieser ID vor dem Einfügen von untergeordneten Datensätzen bedeutet. Das ist eine Menge Hin und Her mit der DB für eine App, die viele Zeilen bestehen muss. – kurosch

0

Hier ist, was ich für die Java-Anwendung kann ich unterstützen

PROCEDURE get_nextvals 
( 
    p_values OUT SYS_REFCURSOR, 
    p_count IN PLS_INTEGER 
) 
IS 
    -- return the next p_count values from the PK sequence 
BEGIN 
    OPEN p_values FOR 
     SELECT 
      <schema>.<sequence>.nextval 
     FROM 
      dual 
     CONNECT BY 
      LEVEL <= p_count 
    ; 
END; 

Es war einfacher, nur eine Tabelle der App verwenden, um einen Cursor, um Java-Pass (die auch Bulk-Einsätze in tief hierarchische Tabellen verwendet) als mit Typ im DB definiert.

+0

Auch hilfreich, ich habe die Tabelle Typ funktioniert, aber ich werde versuchen, auf diese Weise zu sehen, ob es einen Unterschied macht. Danke Leute! – stuckAtWork

1

Eine andere Option könnte sein, die Klausel RETURNING zu verwenden, um die Sequenzwerte nach dem Einfügen automatisch zurückzugeben.