Tengo una secuencia utilizada para la semilla de mi (Entero) llave primaria de una tabla de oracle.

Parece que esta secuencia no siempre ha sido utilizado para insertar nuevos valores en la tabla. ¿Cómo puedo obtener la secuencia de nuevo en el paso con los valores reales en la mesa?

OriginalEl autor AJM | 2009-09-15

6 Comentarios

  1. 16

    Si el IDENTIFICADOR es el nombre de su PK columna y PK_SEQ es el nombre de la secuencia:

    1. Encontrar el valor más alto de la PK por
      SELECT MAX(ID) FROM nombretabla

    2. Encontrar el valor de la siguiente PK_SEQ por
      SELECCIONE PK_SEQ.NEXTVAL DE DOBLE

    3. Si #2 > #1, entonces no hay nada para
      hecho, suponiendo que el tratamiento de estos
      valores como el verdadero sustituto claves
    4. De otra manera, alterar la secuencia de los
      saltar a la max ID por ALTERAR la SECUENCIA de
      PK_SEQ INCREMENTO de [#1 valor – #2
      valor]
    5. Protuberancia de la secuencia, SELECCIONE
      PK_SEQ.NEXTVAL DE DOBLE

    6. Restablecer la secuencia de valor de incremento
      1 por ALTERAR la SECUENCIA de PK_SEQ
      EL INCREMENTO POR 1

    Todo esto se supone que no tienen inserciones en la tabla mientras que usted está haciendo esto…

    Yo estoy luchando con cómo hacer el paso 3, he probado diferentes sintaxis, pero no puedo conseguir que funcione
    La intención de el paso 3 es para comparar el mayor valor PK a la siguiente secuencia de valor. Así, por ejemplo, si la selección del paso 1 se tradujo en un resultado de 100, y SELECCIONAR desde el paso 2 se tradujo en un resultado de 90 que significa que usted tiene que «saltar» 11 secuencias. Cuando se altera la secuencia en el paso 4, SELECCIONE en el paso 5 se moverá la secuencia de 10 valores, a 100. Después del incremento que se restablezca en el paso 6, el siguiente», SELECCIONE PK_SEQ.NEXTVAL DE DOBLE» le dará 101.
    En el paso 4 no me puedo meter la sintaxis para hacer una resta en el Incremento de la cláusula. He tratado de [a-b] a-b y selecr a-b dual, pero sin ningún éxito.
    Lo siento – se ve como si yo no estaba claro – usted tiene que determinar el valor de (N) y, a continuación, utilice la declaración de «ALTERAR la SECUENCIA de PK_SEQ INCREMENTO de N» – yo estaba usando la sintaxis yo siempre como una especie de seudo código.
    Había intentado eso, pero el problema era un syntaticall problema que yo estaba tontamente no anexar mi variable proparly por ejemplo, EJECUTAR INMEDIATO ‘ALTERAR la SECUENCIA de NEXT_VALIDATED_TABLE_ID INCREMENTO POR’ || N ;

    OriginalEl autor dpbradley

  2. 11

    En resumen, el juego es:

    -- Current sequence value is 1000
    
    ALTER SEQUENCE x INCREMENT BY -999;
    Sequence altered.
    
    SELECT X.NEXTVAL FROM DUAL;
    1
    
    ALTER SEQUENCE x INCREMENT BY 1;
    Sequence altered.

    Usted puede obtener el máximo valor de secuencia utilizado dentro de su tabla, no las matemáticas, y la actualización de la secuencia en consecuencia.

    Cómo es esta ayudando. Si el max id de la tabla es de 624. ¿Cómo es el de arriba va a establecer correctamente la ss?

    OriginalEl autor David Andres

  3. 8
    Declare
      difference INTEGER;
      sqlstmt varchar2(255);
      sequenceValue Number;
    begin
    sqlstmt := 'ALTER SEQUENCE YOURSEQUENCE INCREMENT BY ';
    select YOURSEQUENCE.NEXTVAL into sequenceValue from dual;
    select  (nvl(Max(YOURID),0) - sequenceValue)+1 into difference from YOURTABLE;
    if difference > 0 then
      EXECUTE IMMEDIATE sqlstmt || difference;
      select  YOURSEQUENCE.NEXTVAL INTO sequenceValue from dual;
      EXECUTE IMMEDIATE sqlstmt || 1;
    end if;
    end;
    Esta pone a 1 por encima de donde debería estar…
    Creo que es porque de select YOURSEQUENCE.NEXTVAL into sequenceValue from dual; en la línea 7, se puede comprobar una alternativa para que en mi respuesta en https://stackoverflow.com/a/45542069/1737973, que recupera all_sequences.last_number WHERE sequence_name = 'YOURSEQUENCE' en lugar de YOURSEQUENCE.NEXTVAL, probablemente conseguir el valor deseado la secuencia de valor de almacenamiento en caché está deshabilitado.

    OriginalEl autor Dieter DHoker

  4. 5

    He hecho este script como no he encontrado un script en línea, que establece dinámicamente todos mi secuencias de la corriente ID más alto. Probado en Oracle 11.2.0.4.

    DECLARE
      difference         INTEGER;
      sqlstmt            VARCHAR2(255) ;
      sqlstmt2           VARCHAR2(255) ;
      sqlstmt3           VARCHAR2(255) ;
      sequenceValue      NUMBER;
      sequencename       VARCHAR2(30) ;
      sequencelastnumber INTEGER;
      CURSOR allseq
      IS
         SELECT sequence_name, last_number FROM user_sequences ORDER BY sequence_name;
    BEGIN
      DBMS_OUTPUT.enable(32000) ;
      OPEN allseq;
      LOOP
        FETCH allseq INTO sequencename, sequencelastnumber;
        EXIT
      WHEN allseq%NOTFOUND;
        sqlstmt  := 'ALTER SEQUENCE ' || sequencename || ' INCREMENT BY ';
        --Assuming: <tablename>_id is <sequencename>
        sqlstmt2 := 'select (nvl(Max(ID),0) - :1)+1 from ' || SUBSTR(sequencename, 1, LENGTH(sequencename) - 3) ;
        --DBMS_OUTPUT.PUT_LINE(sqlstmt2);
        --Attention: makes use of user_sequences.last_number --> possible cache problems!
        EXECUTE IMMEDIATE sqlstmt2 INTO difference USING sequencelastnumber;
        IF difference > 0 THEN
          DBMS_OUTPUT.PUT_LINE('EXECUTE IMMEDIATE ' || sqlstmt || difference) ;
          EXECUTE IMMEDIATE sqlstmt || difference;
          sqlstmt3 := 'SELECT ' || sequencename ||'.NEXTVAL from dual';
          DBMS_OUTPUT.PUT_LINE('EXECUTE IMMEDIATE ' || sqlstmt3 || ' INTO sequenceValue') ;
          EXECUTE IMMEDIATE sqlstmt3 INTO sequenceValue;
          DBMS_OUTPUT.PUT_LINE('EXECUTE IMMEDIATE ' || sqlstmt || 1) ;
          EXECUTE IMMEDIATE sqlstmt || 1;
          DBMS_OUTPUT.PUT_LINE('') ;
        END IF;
      END LOOP;
      CLOSE allseq;
    END;

    OriginalEl autor Blama

  5. 0

    En algunos casos, usted puede encontrar que es más fácil de obtener sólo el actual valor máximo y, a continuación,

    drop sequence x;
    create sequence x start with {current max + 1};

    La aplicación va a ser roto después de la caída. Pero que va a mantener a nadie a partir de la inserción de filas durante ese período, y la creación de una secuencia rápida. Asegúrese de volver a crear cualquier subvenciones en la secuencia, ya que esos serán descartados cuando la secuencia es. Y es posible que desee volver a compilar manualmente cualquier plsql que depende de la secuencia.

    Me gustaría evitar el abandono de la db objeto si hay una alternativa. Dejar caer la secuencia no impide necesariamente que se inserta en la tabla de la que no se hace referencia a la secuencia. Como usted bien señala usted también tiene el trabajo extra de la captura de las subvenciones y volver a compilar objetos dependientes.

    OriginalEl autor Jim Hudson

  6. 0

    La adición de hasta https://stackoverflow.com/a/15929548/1737973, pero sin recurrir a la SEQUENCENAME.NEXTVAL, por tanto, no resulta en una posición en que debe ser:

    DECLARE
      difference INTEGER;
      alter_sequence_statement VARCHAR2 (255);
      sequence_value NUMBER;
    BEGIN
      --   Base for the statement that will set the sequence value.
      alter_sequence_statement :=
          'ALTER SEQUENCE SEQUENCENAME INCREMENT BY ';
    
      --   Fetch current last sequence value used.
      SELECT
        --   You could maybe want to make some further computations just
        -- below if the sequence is using caching.
        last_number
      INTO sequence_value
      FROM all_sequences
      WHERE sequence_owner = 'SEQUENCEOWNER' AND sequence_name = 'SEQUENCENAME';
    
      --   Compute the difference.
      SELECT max(id) - sequence_value + 1 INTO difference
      FROM SCHEMANAME.TABLENAME;
    
      IF difference <> 0 THEN
        --   Set the increment to a big offset that puts the sequence near
        -- its proper value.
        EXECUTE IMMEDIATE alter_sequence_statement || difference;
    
        --   This 'sequence_value' will be ignored, on purpose.
        SELECT SEQUENCENAME.NEXTVAL INTO sequence_value FROM dual;
    
        --   Resume the normal pace of incrementing one by one.
        EXECUTE IMMEDIATE alter_sequence_statement || 1;
      END IF;
    END;

    Descargo de responsabilidad: si la secuencia está utilizando el almacenamiento en caché (all_sequences.cache_size conjunto más grande que 0) probablemente querer tomar en consideración, en la Calcular la diferencia paso.

    La documentación de Oracle para todas las secuencias.

    Oh, bueno, lo siento esto es para Oracle 11, no sé si se puede trabajar en Oracle 9 sin cambios.

    OriginalEl autor uprego

Dejar respuesta

Please enter your comment!
Please enter your name here