Usando tabela DUAL ou não?

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
marcelo0906
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 34
Registrado em: Qua, 02 Set 2009 3:29 pm
Localização: São José - SC

Bom dia pessoal!

tenho uma dúvida sobre o seguinte,


tenho uma seqüencia e tal, dentro do pl qual seria a maneira com melhor performace para buscar esse valor:

jogando esse valor dentro de uma variavel direto ou seja :

Selecionar tudo

v_teste := seq_x.NEXTVAL
ou utilizando a tabela DUAL

Selecionar tudo

SELECT seq_x.NEXTVAL                                                                                                                                                                      
        INTO   v_teste                                                                                                                                                                                
        FROM   DUAL; 

qual melhor maneira de utilizar ?? com melhor performance??
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

se você fazer isso

Selecionar tudo

v_teste := seq_x.NEXTVAL 
em algum momento você vai utilizar a sua variavel v_teste.. sera somente uma vez ou mais de uma??

se for uma vez somente.. faca seq_x.NEXTVAL direto no lugar

se for utilizar mais de uma vez faca isso mesmo

Selecionar tudo

v_teste := seq_x.NEXTVAL
marcelo0906
Rank: Programador Pleno
Rank: Programador Pleno
Mensagens: 34
Registrado em: Qua, 02 Set 2009 3:29 pm
Localização: São José - SC

e usar a tabela dual como abaixo?

Selecionar tudo

SELECT seq_x.NEXTVAL 
INTO v_teste 
FROM DUAL;
pergunto isso porque na procedure que estou mexendo está feito dessa forma, mas preciso melhorar a performance dela, por isso a dúvida...
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

sinceramente o ganho que você tera sera ínfimo.. mas se você deixa de fazer um select em uma tabela e usa somente a chamada de uma funcao, há ganho..

sobre a tabela dual

Selecionar tudo

The Oracle DUAL table
		
dual is a table which is created by oracle along with the data dictionary. It consists of 
exactly one column whose name is dummy and one record. The value of that record is X.

rene@ora92> desc dual
 Name                    Null?    Type
 ----------------------- -------- ----------------
 DUMMY                            VARCHAR2(1)

rene@ora92> select * from dual;

D
-
X

The owner of dual is SYS but dual can be accessed by every user.
As dual contains exactly one row (unless someone fiddled with it), it is guaranteed to 
return exactly one row in select statements. Therefor, dual is the prefered table to select 
a pseudo column (such as sysdate

select sysdate from dual

Although it is possible to delete the one record, or insert additional records, one really 
should not do that!. 
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Não é possível atribuir nextval de uma sequence a uma variável por PL/SQL, tem que usar o select from dual.

Selecionar tudo

SQL> create sequence seq_test start with 1
  2                           increment by 1
  3                           nocache
  4                           nocycle;

Seqüência criada.

SQL> declare
  2    var_test number;
  3  begin
  4    var_test := seq_test.nextval;
  5  end;
  6  /
  var_test := seq_test.nextval;
                       *
ERRO na linha 4:
ORA-06550: line 4, column 24:
PLS-00357: Table,View Or Sequence reference 'SEQ_TEST.NEXTVAL' not allowed in
this context
ORA-06550: line 4, column 3:
PL/SQL: Statement ignored


SQL> declare
  2    var_test number;
  3  begin
  4    select seq_test.nextval into var_test from dual;
  5  end;
  6  /

Procedimento PL/SQL concluído com sucesso.

SQL> drop sequence seq_test;

Seqüência eliminada.

SQL> 
O que você pode fazer para agilizar o processo é, em vez de dar um select para cada nextval, fazer into para um array, ou direto no seu insert.

Selecionar tudo

SQL> create sequence seq_test start with 1
  2                           increment by 1
  3                           nocache
  4                           nocycle;

Seqüência criada.

SQL> declare
  2    type t_array is table of number;
  3    tab_test t_array;
  4  begin
  5    select seq_test.nextval bulk collect into tab_test
  6      from (select level from dual connect by level <= 10);
  7  end;
  8  /

Procedimento PL/SQL concluído com sucesso.

SQL> create table t1 as
  2  select seq_test.nextval
  3  from (select level from dual connect by level <= 10);

Tabela criada.

SQL> select * from t1;

   NEXTVAL
----------
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20

10 linhas selecionadas.

SQL> 
Avatar do usuário
fsitja
Rank: OraSauro
Rank: OraSauro
Mensagens: 611
Registrado em: Seg, 19 Jan 2009 4:29 pm
Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html

OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist

Corrigindo a informação que coloquei acima, não tinha me tocado que no Oracle 11g já é aceita atribuição direta de nextval em variável. Rodei o código acima no 10g do trabalho e não no meu 11g em casa.
se você fazer isso

Selecionar tudo

v_teste := seq_x.NEXTVAL
em algum momento você vai utilizar a sua variavel v_teste.. sera somente uma vez ou mais de uma??

se for uma vez somente.. faca seq_x.NEXTVAL direto no lugar

se for utilizar mais de uma vez faca isso mesmo

Selecionar tudo

v_teste := seq_x.NEXTVAL 
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante