Frage

Ich habe eine Sequenz mit 1 mit einem maximalen Wert erstellt Ich habe einen Trigger für das automatische Einfügen von Primärschlüssel erstellt, das unten ist Ich habe auch eine Einschränkung für den Tisch eingestellt, in dem der Primärschlüssel eindeutig sein muss und nicht null generasacodicetagpre.

Ergebnis:

Fehler in Zeile 1:
Ora-00001: Eindeutige Einschränkung (user.pk_my_temp) verletzt

Die Tabelle my_temp enthält bereits Werte ab 1 bis 338 FRO-ID-Feld

Also, wie sollte ich das in Triggern und in den Anweisungen in den Einfügen umgehen.

War es hilfreich?

Lösung

You can increment your sequence before you install the trigger:

declare 
  v_max_id my_temp.id%type;
  v_curr_seq  NUMBER;
begin
  select max(id) into v_max_id from my_temp;

  loop
    select MY_TEMP_SEQ.nextval into v_curr_seq from dual;
    exit when v_curr_seq >= v_max_id;
  end loop;
end;
/

Andere Tipps

If you really do want the option to specify your own ID value on insert, and rely on the trigger using the sequence at other times, then your trigger needs to check whether it was passed a value - otherwise the trigger-generated ID will take precedence (and if you specify MY_TEMP_SEQ.nextval in the insert, that value will be skipped).

BEGIN
    IF :NEW.id IS NULL THEN
        SELECT MY_TEMP_SEQ.nextval 
        INTO :NEW.id 
        FROM DUAL;
    END IF;
END;

Dealing with values that already exist is more complicated. If you weren't ever going to pass your own (non-sequence) ID value in then you could just roll the sequence forward to the highest existing value, e.g.:

ALTER SEQUENCE MY_TEMP_SEQ INCREMENT BY 338; -- or however many you need to skip
SELECT MY_TEMP_SEQ.nextval FROM DUAL;
ALTER SEQUENCE MY_TEMP_SEQ INCREMENT BY 1;

Where you'll have a problem is if you try to insert a record manually specifying a ID value without using the sequence, which is larger than the sequence (say using 500). When the sequence (eventually) gets to that value you'll still get an ORA-00001.

I don't think you can handle that, or your immediate problem, within the trigger; I believe you'd get a mutating table error if you tried to check for an existing value in the same table, and the workarounds for that just add complication (three triggers are needed) and potentially instability. As far as I'm aware the only simple way to deal with that scenario would be to wrap the insert in a procedure instead and block direct inserts, which may not be an option either. You only need to worry about this if you'll ever insert values without using the sequence, though.

You can't use both - only one or the other.
In your example, the id value is already inserted as the next value of the sequence... which is the same value the trigger attempts to use. I might have the order backwards, but the result is the same.

The trigger is not necessary if you'll be referencing the sequence in the INSERT statement:

INSERT INTO my_temp  
  (Id,Type, CreateDT, TypeId, TempType, DevType, Msg, File,User, Src, SrcDev)   
VALUES
  (MY_TEMP_SEQ.nextval,3434,2843,2453,2392,435,2390,'pension.txt','rereee',454545,3434);

If Using the Trigger

Having the trigger means you can't use the id column in the INSERT:

INSERT INTO my_temp  
  (Type, CreateDT, TypeId, TempType, DevType, Msg, File,User, Src, SrcDev)   
VALUES
  (3434, 2843, 2453, 2392, 435, 2390, 'pension.txt', 'rereee', 454545, 3434);

Most like the trigger approach because they're used to either MySQL AUTOINCREMENT, or SQL Server's IDENTITY (Denali will finally support the ANSI sequences).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top