Func ou proc do ORACLE equivalente a sp_executesql do SQL

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
tadeu.oliveira
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Sex, 01 Jul 2016 11:10 am

Senhores.
Existe no ORACLE alguma função ou store procedure equivalente a sp_executesql do MS-SQL server?
Pois estou tentando executar uma query dinâmica no ORACLE utilizando execute immediate e não está dando certo.
Descobri que o execute immediate só roda comandos como CREATE, INSERT e etc. mas não executa SELECT de forma direta.
Estou deixando o código abaixo para ser mais claro e conto com a ajuda dos colegas.

Selecionar tudo

declare 
  vCampos varchar2(20000);
  vSQL_1  varchar2(20000);
begin
  vCampos := '''Processo - N.T.''' || ', ' || '''Produto Acabado - N.T.''' || ', ' || '''Inspeção''' || ', ' || '''Produto Acabado - Rodovia''';   
  vSQL_1  := 'create or replace view mgcli.vw_teste as 
  select * from  
           (
            select t.fil_in_codigo                Filial
            ,      t.pro_in_codigo                Codigo_Mega
            ,      p.pro_st_alternativo           Codigo_Antigo
            ,      cc.pro_in_codigo_inteligente   Codigo_Inteligente
            ,      p.pro_st_descricao             Descrição
            ,      p.unip_st_unidade              UN
            ,      a.alm_st_almoxar               Almoxarifado
            ,      t.mvs_re_quantidade            Qtde
            from   mgadm.est_movsumarizado        t
            ,      mgadm.est_produtos             p
            ,      mgadm.est_almoxarifado         a
            ,      mgadm.est_produtoscmpesp       cc
            where  t.org_in_codigo = 1031 
            and    p.gru_ide_st_codigo            in (00,01,04)
            and    p.cla_gru_in_codigo            in (1,130) 
            and    t.pro_tab_in_codigo            =  p.pro_tab_in_codigo
            and    t.pro_pad_in_codigo            =  p.pro_pad_in_codigo
            and    t.pro_in_codigo                =  p.pro_in_codigo
            and    t.alm_pad_in_codigo            =  a.alm_pad_in_codigo
            and    t.alm_tab_in_codigo            =  a.alm_tab_in_codigo
            and    t.alm_in_codigo                =  a.alm_in_codigo
            and    p.pro_tab_in_codigo            =  cc.pro_tab_in_codigo (+)
            and    p.pro_pad_in_codigo            =  cc.pro_pad_in_codigo (+)
            and    p.pro_in_codigo                =  cc.pro_in_codigo     (+)
          )            
          pivot 
          (
           sum(Qtde)
           for Almoxarifado IN  (' || vCampos || ') 
          )
         order by 1, 3;'; 
  execute immediate(vSQL_1); --Erros apresentados: caractere inválido ou palavra-chave não encontrada.
-- no SQL Server isso rodaria assim  exec sp_executesql vSQL_1;         
end;
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

Mas pode usar EXECUTE IMMEDIATE com Select.

Aqui tem vários exemplos:

Selecionar tudo

DECLARE
   sql_stmt    VARCHAR2(200);
   plsql_block VARCHAR2(500);
   emp_id      NUMBER(4) := 7566;
   salary      NUMBER(7,2);
   dept_id     NUMBER(2) := 50;
   dept_name   VARCHAR2(14) := 'PERSONNEL';
   location    VARCHAR2(13) := 'DALLAS';
   emp_rec     emp%ROWTYPE;
BEGIN
   EXECUTE IMMEDIATE 'CREATE TABLE bonus (id NUMBER, amt NUMBER)';
   sql_stmt := 'INSERT INTO dept VALUES (:1, :2, :3)';
   EXECUTE IMMEDIATE sql_stmt USING dept_id, dept_name, location;
   sql_stmt := 'SELECT * FROM emp WHERE empno = :id';
   EXECUTE IMMEDIATE sql_stmt INTO emp_rec USING emp_id;
   plsql_block := 'BEGIN emp_pkg.raise_salary(:id, :amt); END;';
   EXECUTE IMMEDIATE plsql_block USING 7788, 500;
   sql_stmt := 'UPDATE emp SET sal = 2000 WHERE empno = :1
      RETURNING sal INTO :2';
   EXECUTE IMMEDIATE sql_stmt USING emp_id RETURNING INTO salary;
   EXECUTE IMMEDIATE 'DELETE FROM dept WHERE deptno = :num'
      USING dept_id;
   EXECUTE IMMEDIATE 'ALTER SESSION SET SQL_TRACE TRUE';
END;
Basta colocar INTO.
tadeu.oliveira
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Sex, 01 Jul 2016 11:10 am

Boa tarde.
Me baseando no seu exemplo de execute immediate com select usando into meu exemplo ficou assim.

Selecionar tudo

declare 
  vCampos varchar2(20000);
  vSQL_1  varchar2(20000);
  vReg    mgadm.est_movsumarizado%rowtype;
begin
  vCampos := '''Processo - N.T.''' || ', ' || '''Produto Acabado - N.T.''' || ', ' || '''Inspeção''' || ', ' || '''Produto Acabado - Rodovia''';   
  vSQL_1  := '
  select * from  
           (
            select t.fil_in_codigo                Filial
            ,      t.pro_in_codigo                Codigo_Mega
            ,      p.pro_st_alternativo           Codigo_Antigo
            ,      cc.pro_in_codigo_inteligente   Codigo_Inteligente
            ,      p.pro_st_descricao             Descrição
            ,      p.unip_st_unidade              UN
            ,      a.alm_st_almoxar               Almoxarifado
            ,      t.mvs_re_quantidade            Qtde
            ,      t.rowid                        reg
            from   mgadm.est_movsumarizado        t
            ,      mgadm.est_produtos             p
            ,      mgadm.est_almoxarifado         a
            ,      mgadm.est_produtoscmpesp       cc
            where  t.org_in_codigo = 1031 
            and    p.gru_ide_st_codigo            in (00,01,04)
            and    p.cla_gru_in_codigo            in (1,130) 
            and    t.pro_tab_in_codigo            =  p.pro_tab_in_codigo
            and    t.pro_pad_in_codigo            =  p.pro_pad_in_codigo
            and    t.pro_in_codigo                =  p.pro_in_codigo
            and    t.alm_pad_in_codigo            =  a.alm_pad_in_codigo
            and    t.alm_tab_in_codigo            =  a.alm_tab_in_codigo
            and    t.alm_in_codigo                =  a.alm_in_codigo
            and    p.pro_tab_in_codigo            =  cc.pro_tab_in_codigo (+)
            and    p.pro_pad_in_codigo            =  cc.pro_pad_in_codigo (+)
            and    p.pro_in_codigo                =  cc.pro_in_codigo     (+)
          )            
          pivot 
          (
           sum(Qtde)
           for Almoxarifado IN  (' || vCampos || ') 
          )
         order by 1, 3;'; 
  execute immediate vSQL_1 into vReg using mgadm.est_movsumarizado.fil_in_codigo;          
end;
Ainda sim recebi a seguinte mensagem de erro: PLS-000357: Table, view or sequence reference mgadm.est_movsumarizado.fil_in_codigo not in allowed in this conetext.

Dentro do meu código como ficaria isto já que o campo que passei pelo que pude entender não é um sequencial automático apesar de ser um campo numérico.

Poderia por gentileza me dar um exemplo dentro do meu código?
Desde já muito obrigado.

Atenciosamente,

Tadeu.
Responder
  • Informação
  • Quem está online

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