Pular para o conteúdo
  • Este tópico contém 9 respostas, 3 vozes e foi atualizado pela última vez 14 anos, 7 meses atrás por diegolenhardt.
Visualizando 10 posts - 1 até 10 (de 10 do total)
  • Autor
    Posts
  • #100196
    eversonpiza
    Participante

      Pessoal,

      Criei uma sequence iniciando em 1, e faço um insert pegando o nextval dela, mas tá inserindo dois na tabela, se eu faço um select seq.nextval from dual trás 1.

      Segue um caso de teste


      SQL> CREATE TABLE tabela_tst (ID NUMBER(10) NOT NULL);

      Table created
      SQL> CREATE SEQUENCE SEQ_tabela_tst INCREMENT BY 1 START WITH 1 MAXVALUE 9999999999 NOCYCLE CACHE 20 ;

      Sequence created
      SQL> INSERT INTO tabela_tst (id) VALUES (SEQ_tabela_tst.nextval) ;

      1 row inserted
      SQL> select t.id from tabela_tst t;

      ID
      -----------
      2


      SQL> CREATE SEQUENCE SEQ_tabela_tst INCREMENT BY 1 START WITH 1 MAXVALUE 9999999999 NOCYCLE CACHE 20 ;

      Sequence created

      SQL> select SEQ_tabela_tst.nextval from dual;

      NEXTVAL
      ----------
      1

      O mesmo teste em uma instância 10g tem o comportamento ‘correto’ esperado.

      #100197
      eversonpiza
      Participante

        Uma nova informação.

        Se eu conectar como “/ as sysdba” ele funciona direitinho, qualquer usuário ‘mortal’ retorna 2.

        #100198
        rman
        Participante

          Executando aqui com um usuario com grant de dba, o retorno é 1.

          Estou utilizando o Oracle Database 10g Release 10.2.0.4.0 – 64bit Production

          Em casa posso testar no Oracle 11g R2…

          #100199
          eversonpiza
          Participante

            Olá “rman”

            Estou desconfiado de algum bug no Oracle 11g, o comportamento é realmente estranho, no 10g nunca vi isso acontecer.

            Se eu conectado como sysdba crio a sequence no SYS e a tabela em um novo owner, ele tb retorna 2.

            Olha o teste que fiz:

            SQL> show user;
            USER is "SYS"
            SQL> create user tst_seq identified by tst_sql default tablespace users;

            User created.

            SQL> alter user tst_seq quota unlimited on users;

            User altered.

            SQL> CREATE TABLE tst_seq.tabela_tst (ID NUMBER(10) NOT NULL);

            Table created.

            SQL> CREATE SEQUENCE SEQ_tabela_tst INCREMENT BY 1 START WITH 1 MAXVALUE 9999999999 NOCYCLE CACHE 20 ;

            Sequence created.

            SQL> INSERT INTO tst_seq.tabela_tst (id) VALUES (SEQ_tabela_tst.nextval) ;

            1 row created.

            SQL> select id from tst_seq.tabela_tst t;

            ID

                 2
            

            #100200
            diegolenhardt
            Participante

              tenta criar a sequence com NOCACHE…

              #100201
              eversonpiza
              Participante

                Oi Diego,

                Já tentei isso 🙁

                #100202
                diegolenhardt
                Participante

                  http://www.stefanocislaghi.eu/2010/06/s … -of-11gr2/

                  o cara diz que tem um parametro no banco pra um recurso novo:

                  SQL> show parameter def

                  NAME TYPE VALUE


                  deferred_segment_creation boolean FALSE

                  veja se é isso mesmo

                  #100204
                  rman
                  Participante

                    Acho que o diegolenhardt matou a questão.

                    Realmente o parâmetro deferred_segment_creation mudou o comportamento, mas um detalhe, nada mudou em relação a sequence, o que mudou foi em relação as tabelas não particionadas e objetos dependentes da tabela como lob e índices, a tabela só é criada de fato, após a primeira inserção de registro.

                    Retirado da documentação oficial:


                    DEFERRED_SEGMENT_CREATION

                    Property Description
                    Parameter type Boolean
                    Default value true
                    Modifiable ALTER SESSION, ALTER SYSTEM
                    Range of values true | false
                    Basic No
                    DEFERRED_SEGMENT_CREATION specifies the semantics of deferred segment creation. If set to true, then segments for non-partitioned tables and their dependent objects (LOBs, indexes) will not be created until the first row is inserted into the table.

                    Before creating a set of tables, if it is known that a significant number of them will not be populated, then consider setting this parameter to true. This saves disk space and minimizes install time.

                    Fiz alguns testes para entender melhor como funciona o parâmetro, por padrão ele é verdadeiro.


                    Connected to Oracle Database 11g Enterprise Edition Release 11.2.0.1.0
                    Connected as sakamoto

                    SQL> CREATE TABLE TABELA_TST (ID NUMBER(10) NOT NULL);

                    Table created

                    SQL> CREATE SEQUENCE SEQ_TABELA_TST INCREMENT BY 1 START WITH 1 MAXVALUE 9999999999 NOCYCLE CACHE 20;

                    Sequence created

                    SQL> INSERT INTO TABELA_TST (ID) VALUES (100);

                    1 row inserted

                    SQL> COMMIT;

                    Commit complete

                    SQL> SELECT T.ID FROM TABELA_TST T;

                    ID

                        100
                    

                    SQL> INSERT INTO TABELA_TST (ID) VALUES (SEQ_TABELA_TST.NEXTVAL) ;

                    1 row inserted

                    SQL> COMMIT;

                    Commit complete

                    SQL> SELECT T.ID FROM TABELA_TST T;

                    ID

                        100
                          1
                    

                    Repare que eu inseri o primeiro registro com valor 100 para sabermos que foi gerado na mão, e não pela sequence. Neste momento a tabela foi criada de fato, em seguida inseri utilizando a sequence, veja que foi inserido o valor 1.

                    O que acontece quando tentamos inserir direto o primeiro registro vindo da sequence ? Provavelmente a sequence gera o valor 1 e tenta inserir na tabela, por algum motivo a inserção falha, é quando a tabela é criada de verdade, então é tentado inserir novamente, é gerado o valor 2, então é inserido com sucesso.

                    Pelos testes foi isso que eu conclui, posso estar falando besteira… ^^

                    #100210
                    eversonpiza
                    Participante

                      Diego,
                      Obrigado.

                      Interessante este parâmetro, e ele realmente resolveu o meu problema.

                      Mas na minha opinião isto continua sendo um BUG, independente do ‘atraso’ na criação da tabela a sequence deveria ter sua ordem respeitada.

                      #100212
                      diegolenhardt
                      Participante

                        rman,

                        parece que é isso mesmo,

                        porque se voce fizer o select com o nextval ele retorna 1, e o insert da zica, portanto o problema ta na tabela mesmo..

                        😀

                        a vantagem pelo que vi é em ambientes de desenvolvimento, pra nao alocar os primeiros segmentos com a criacao dos objetos. mas sei lá

                      Visualizando 10 posts - 1 até 10 (de 10 do total)
                      • Você deve fazer login para responder a este tópico.