Arrays em PLSQL

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
lopes_andre
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 49
Registrado em: Seg, 13 Out 2008 9:01 am
Localização: Lisboa

Viva,

Estou a fazer um programa em PLSQL que irá fazer um sorteio. Este sorteio além de ser random tem também uma ponderação.

Estou-me a basear neste programa em excel: http://www.dailydoseofexcel.com/archive ... dom-sorts/

Eu queria saber qual será a melhor maneira de lidar com a seguinte situação:

No meu caso, atribui ponderações as categorias da empresa. O empregado irá ter um valor de ponderação igual ao da sua categoria.

Se a ponderação da categoria do empregado XPTO tiver o valor 6 eu teria de criar um array com 6 valores, cada um desses valores seria gerado segundo a formula -->

Selecionar tudo

=(RAND()^LOG(1-1/(6+1); 0,5))*1000
esta formula é ainda uma formula em excel. Desses 6 valores gerados pela formula no array eu iria escolher o mais alto.

Isto será possivel de fazer em PLSQL ou terei de tomar outro caminho?


Desde já obrigado.

Cumprimentos,
André.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Acho que não tem problema.
Pra fazer número randômicos, pode-se usar DBMS_RAND.
http://glufke.net/oracle/viewtopic.php?p=7496
http://glufke.net/oracle/viewtopic.php?t=243

Selecionar tudo

SQL> select dbms_random.random from dual;

    RANDOM
----------
-1.262E+09

SQL> /

    RANDOM
----------
 619010116

SQL> /

    RANDOM
----------
 406715840

SQL> /

    RANDOM
----------
-615930667

SQL>  

Pra fazer LOG, também não é problema:
http://www.techonthenet.com/oracle/functions/log.php

Selecionar tudo

SQL> select log(10, 100) from dual;

LOG(10,100)
-----------
          2

SQL> 
Agora, é só montar algo que busque esses resultados e pegue o maior deles...
Trevisolli
Moderador
Moderador
Mensagens: 2016
Registrado em: Qua, 12 Jan 2005 3:25 pm
Localização: Araraquara - SP
Abraço,

Trevisolli
OCA Oracle PL/SQL Developer Certified Associate
OCP Oracle Forms Developer Certified Professional
Araraquara-SP

Show de bola, Dr_Gori.

Só complementando, para se pegar o maior valor, pode ainda usar o GREATEST (Se não me engano 9i e superiores):

Selecionar tudo

SELECT GREATEST (2, 5, 12, 3) maior_valor
  FROM DUAL;
Retorna: 12.

Qualquer coisa, tamos aí.
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5024
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Mandou bem!

Mas eu acho que talvez ele vai ter que usar outra forma de pegar o maior. Talvez inserir numa global temporary table (caso não seja fixo o número máximo da "ponderação" dele...

Isso porque é impossível fazer GREATEST de um array.
Exemplo:

Selecionar tudo

SQL> declare
  2   TYPE ARRAY IS TABLE OF number INDEX BY BINARY_INTEGER;
  3   
  4   t ARRAY;
  5   
  6  begin
  7  
  8    t(1) :=10;
  9    t(2) :=20;
 10    t(3) :=30;
 11    
 12    dbms_output.put_line ( greatest(t) );
 13  
 14  
 15  end;
 16  /
  dbms_output.put_line ( greatest(t) );
                         *
ERROR at line 12:
ORA-06550: line 12, column 26:
PLS-00306: wrong number or types of arguments in call to 'GREATEST'
ORA-06550: line 12, column 3:
PL/SQL: Statement ignored


SQL>  
Acho que é melhor inserir os valores numa GTT e fazer MAX simplesmente.
lopes_andre
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 49
Registrado em: Seg, 13 Out 2008 9:01 am
Localização: Lisboa

Viva,

Desde já muito obrigado pela ajuda!

Já estou a construir o programa, no entanto estou com dificuldade com o DBMS_RANDOM. Não vou trabalhar com arrays, vou antes enviar os valores gerados para uma tabela temporaria, vai simplificar bastante as coisas... agora o entrave..

No excel estou usando esta formula:

Selecionar tudo

=RAND()^LOG(1-1/(N+1);0,5)
Quanto mais aproximo o N de 10 que será o peso/ponderação máxima mais provavel será serem gerados valores proximos de 1.

Fazer random de um LOG no excel funciona bem. No oracle não estou a conseguir fazer random de um LOG. Será que tem jeito de fazer random de um LOG?


Desde já obrigado.

Melhores cumprimentos
André.
ricardorauber
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 96
Registrado em: Qua, 21 Jun 2006 11:33 pm
Localização: Canoas RS

Daria para fazer assim também:

Selecionar tudo

DECLARE

  TYPE nums IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
  vetor nums;
  
  FUNCTION maior RETURN NUMBER IS
    cont NUMBER := 0;
  BEGIN
    FOR i IN vetor.FIRST .. vetor.LAST LOOP
      IF vetor(i) > cont THEN
        cont := vetor(i);
      END IF;
    END LOOP;
    RETURN cont;
  END maior;
  
BEGIN

  vetor(1) := 3;
  vetor(2) := 5;
  vetor(3) := 4;
  
  dbms_output.put_line(maior);
  
END;
ricardorauber
Rank: Analista Júnior
Rank: Analista Júnior
Mensagens: 96
Registrado em: Qua, 21 Jun 2006 11:33 pm
Localização: Canoas RS

Para calcular exponencial, random e log

Selecionar tudo

DECLARE

  TYPE nums IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;
  vetor nums;
  
BEGIN

  -- LOG(1-1/(1+A1);0,5)

  -- Insere valores
  FOR i IN 1 .. 10 LOOP
    vetor(i) := i;
    dbms_output.put_line(vetor(i));
  END LOOP;
  
  -- Separador
  dbms_output.put_line(rpad('-',100,'-'));
  
  -- Adiciona o log
  FOR i IN vetor.FIRST .. vetor.LAST LOOP
    vetor(i) := LOG(0.5,1-1/(1+vetor(i)));
    dbms_output.put_line(vetor(i));
  END LOOP;
  
  -- Separador
  dbms_output.put_line(rpad('-',100,'-'));
  
  -- Adiciona o random e calcula a potencia (exponencial)
  FOR i IN vetor.FIRST .. vetor.LAST LOOP
    vetor(i) := power(trunc(dbms_random.value(1,10)), vetor(i));
    dbms_output.put_line(vetor(i));
  END LOOP;
  
END;
Saída:

Selecionar tudo

1
2
3
4
5
6
7
8
9
10
----------------------------------------------------------------------------------------------------
1
,5849625007211561814537389439478165087624
,41503749927884381854626105605218349124
,3219280948873623478703194294893901758618
,2630344058337938335834195144584263329081
,22239242133644792598823037328401429991
,1926450779423958925580306827681691913527
,1699250014423123629074778878956330175169
,1520030934450499849628415415937571583599
,1375035237499349083290436172364027828474
----------------------------------------------------------------------------------------------------
2
1,90150749823037254511681818840789155874
1,77777777777777777777777777777777777777
2,02860491380619980243290499234874746619
1,78237306890983628007321950484593599572
1,1666666666666666666666666666666666667
1,45480229597148250562035976049055480278
1,45261210788256229152408722218618633821
1,37174211248285322359396433470507544584
1,09999999999999999999999999999999999999
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 13 visitantes