Pular para o conteúdo
  • Este tópico contém 6 respostas, 2 vozes e foi atualizado pela última vez 18 anos atrás por Ishii.
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #80846
    sp66d_rac6r
    Participante

      Pessoal,
      Em minha procedure, faço acesso a uma tabela que é particionada por data.

      Preciso alterar meu select, para que acesse apenas a partição da data que estou processando.

      Isto deve ser dinâmino e não pode ser via “execute immediate”.

      Alguem pode ajudar?

      Grato!

      #80856
      Ishii
      Participante

        Você já tentou utilizar o dbms_sql? Se ainda não dê uma olhada em
        http://download.oracle.com/docs/cd/B193 … sthref1114

        []s Ishii

        #80860
        sp66d_rac6r
        Participante

          Ishii, se eu entendi, o sql (cursor) fica como texto, certo?

          Se for isto, não posso usar assim.

          A qry tem muitas regras, e desta forma (texto) não tem como detectar erros em compilação.

          Estou certo?

          #80861
          sp66d_rac6r
          Participante

            Ah, esqueci de dizer que estou usando BULK COLLECT e FOR ALL.

            #80862
            Ishii
            Participante

              Sim o cursor vai ficar como texto e pode ocorrer erros de compilação mas somente se a regra não estiver bem definida se estiver ok deve funcionar bem. Outra alternativa seria colocar as condições em uma proc concatenando o select com as condições conforme as suas necessidades e executando dinamicamente mas acho que pode ser que a proc fique bem extensa. Já tivemos um caso de uma proc com cerca de 3000 linhas somente para montar a query e substituimos tudo pelo dbms_sql com umas 100 linhas mas é lógico que a foi feita uma revisão das regras. Mas mesmo assim usamos um dbms_output para “resgatar” a query a ser executada para corrigir eventuais problemas…

              []s Ishii

              #80863
              sp66d_rac6r
              Participante

                O que tentei fazer foi isto:

                create procedure p_xxxx (pd_data_refe in DATE) is

                vc_nome_particao varchar2(30);

                cursor C_INSERE_DADOS (vc_nome_particao VARCHAR2) is
                SELECT *
                from PARTITION (vc_nome_particao)
                WHERE ….. ;

                begin
                SELECT PARTITION_NAME
                INTO vc_nome_particao
                FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = ‘TB_PRE_AUXI_AGRE_OFER_BASI’ AND
                PARTITION_NAME = ‘P_’ ||TO_CHAR(PD_DATA_REFE,’YYYYMMDD’);

                OPEN C_INSERE_DADOS (vc_nome_particao );
                LOOP
                FETCH C_INSERE_DADOS BULK COLLECT
                INTO …… LIMIT cc_limit;

                — inicia o cursor
                FORALL i IN v_cd_banc.FIRST .. v_cd_banc.LAST

                INSERT INTO ….

                end;

                Mas deu erro, dizendo que a partição ñ existe.

                O Oracle entende o nome da variável, sendo o nome da partição.

                Tem como dar um “gato” no Oracle p/ que ele entenda que é uma variável e ñ o nome da partição?

                #80864
                Ishii
                Participante

                  Não consegui testar direito aqui mas deve funcionar:

                  create procedure p_xxxx (pd_data_refe in DATE) is

                  — Cursor

                  type cursor_ins_data is ref cursor;

                  C_INSERE_DADOS cursor_ins_data;
                  vc_stmt_select varchar2(2000);



                  vc_nome_particao varchar2(30);

                  begin
                  SELECT PARTITION_NAME
                  INTO vc_nome_particao
                  FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = ‘TB_PRE_AUXI_AGRE_OFER_BASI’ AND
                  PARTITION_NAME = ‘P_’ ||TO_CHAR(PD_DATA_REFE,’YYYYMMDD’);



                  vc_stmt_select := ‘SELECT * from PARTITION (‘||vc_nome_particao||’)’;


                  OPEN C_INSERE_DADOS for vc_stmt_select; —
                  LOOP
                  FETCH C_INSERE_DADOS BULK COLLECT
                  INTO …… LIMIT cc_limit;

                  — inicia o cursor
                  FORALL i IN v_cd_banc.FIRST .. v_cd_banc.LAST

                  INSERT INTO ….

                  end;

                  Se tiver que fazer algum ajuste, como já disse cap. Nascimento: ‘senta o dedo nessa p…ra’

                  []s Ishii

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