Converter uma variavel do tipo string para um objeto

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
Eder
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 13 Jul 2010 10:38 am
Localização: MG

Boa tarde, Pessoal!


Estou com uma dúvida, vocês podem me ajudar?

Existe a possibilidade, ou uma outra maneira, de eu receber o nome de uma tabela em uma variavel e dentro de um bloco pl/sql realizar um select, por exemplo? Segue um simples exemplo:

Selecionar tudo

declare

tab1          varchar2(30) := 'tab_cliente'; --NOME DA TABELA
vNome      varchar2(30);
begin

select nome_cli into vNome from tab1 -- Aqui a var com o nome da tab;
where cod_cli = 1;

end;
Outra dúvida,existe no oracle um comando que executa uma string de instrução como o EXEC do sql server?

desde já agradeço
rafaelfrocha
Rank: Programador Sênior
Rank: Programador Sênior
Mensagens: 45
Registrado em: Qua, 31 Out 2007 9:30 am
Localização: Uberlândia
Rafael Rocha

Não conheço de SQL Server, mais creio que o "execute immediate" do Oracle deva ser equivalente.

Tem tópicos aqui no forum que citam esta funcionalidade.
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

Eder
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 13 Jul 2010 10:38 am
Localização: MG

entendi..pessoal vou dar uma olhada no execute immediate,mas na questao de passar o nome da tabela em uma variavel e fazer um select por exemplo nesta variavel? É possivel
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

Selecionar tudo

select table_name into vNome from all_tables where ? = ?;
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

Olá Eder,

É possível executar SQL dinâmico nessa forma, concatenando o nome da tabela no SQL, mas é fortemente recomendado que seja a última alternativa de solução. SQL dinâmico é geralmente útil em casos onde sem ele você precisaria escrever muito mais código e ficaria uma solução muito mais complexa com SQL estático.

Seguem alguns pontos relevantes na minha opinião:

- SQL dinâmico e concatenação de strings em SQL tornam o código vulnerável a SQL injection, que é uma falha grave de segurança em aplicações de banco de dados. Esteja consciente disso e valide sempre os strings recebidos para concatenar. Leia sobre a package DBMS_ASSERT.
http://download.oracle.com/docs/cd/E118 ... assert.htm
- SQL estático tem a sintaxe validada em tempo de compilação. SQL Dinâmico não.
- SQL estático é validado em tempo de compilação para garantir que o usuário tenha os grants necessários para realizar a operação. Dinâmico não.
- Como consequência seu código muito mais complicado de manter e aparelhar para fazer debug; e muito mais sujeito a erros.
- SQL estático em PL/SQL utiliza binding de variáveis (parâmetros no where) automaticamente. No SQL dinâmico você precisa fazer manualmente ou então está sujeito a fazer parse do SQL repetidamente, acabando com a performance do BD.

Tenho certeza que há mais pontos que poderiam ser reforçados mas isso é o que eu consegui lembrar agora.

Tem mais informações sobre SQL dinâmico no link abaixo:
http://download.oracle.com/docs/cd/E118 ... ynamic.htm
Eder
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 10
Registrado em: Ter, 13 Jul 2010 10:38 am
Localização: MG

Entendi..
Vou estudar mais a respeito e ver se encontro outra solução para o problema.

Obrigado a todos pela ajuda
ivairb
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Qui, 30 Dez 2010 4:34 pm
Localização: Fortlaeza - CE

Boa tarde.

Estou com o mesmo impasse.
Só que preciso do nome do campo na tabela.
Isso me economizaria muitos selects, pois as tabelas são grandes.

Este é o código:

Selecionar tudo

   FUNCTION SP_INT_POPULAR_LINHA(PI_TABELA VARCHAR2, PI_CHAVE VARCHAR, PI_ID NUMBER, PI_DADOS GSH_INTEGRA_SAIDA_PESSOA%ROWTYPE) RETURN VARCHAR2
   IS
     LINHA VARCHAR2(10000);
     W_SQL VARCHAR2(255);
     W_VALOR VARCHAR2(3000);
     W_CAMPO VARCHAR2(255); 
   BEGIN
      LINHA := NULL;
      FOR R IN (SELECT C.COLUMN_NAME, C.DATA_TYPE, C.DATA_LENGTH 
                     FROM USER_TAB_COLUMNS C 
                     WHERE C.TABLE_NAME = PI_TABELA
                     ORDER BY c.COLUMN_ID) 
      LOOP
         IF R.DATA_TYPE IN ('VARCHAR', 'VARCHAR2', 'CHAR') THEN
            W_CAMPO := 'RPAD(NVL('|| R.COLUMN_NAME ||', '' ''), ' || R.DATA_LENGTH || ', '' '')';
         ELSIF R.DATA_TYPE = 'DATE' THEN
            IF R.DATA_LENGTH <= 10 THEN
               W_CAMPO := 'NVL(TO_CHAR(' || R.COLUMN_NAME ||', ''DD/MM/YYYY''), ''          '')'; 
            ELSE
               W_CAMPO := 'NVL(TO_CHAR(' || R.COLUMN_NAME ||', ''DD/MM/YYYY HH24:MI:SS''), ''                     '')'; 
            END IF;
         ELSIF R.DATA_TYPE = 'NUMBER' THEN
            IF R.DATA_LENGTH > 0 THEN
               W_CAMPO := 'LPAD(NVL(' || R.COLUMN_NAME ||', 0), ' || R.DATA_LENGTH || ', 0)';
            ELSE
               W_CAMPO := 'LPAD(NVL(' || R.COLUMN_NAME ||', 0), 32 , 0)';
            END IF;
         END IF;

         
         W_SQL := 'SELECT ' || W_CAMPO || ' FROM ' || PI_TABELA || ' WHERE ' || PI_CHAVE || ' = ' || PI_ID;
         EXECUTE IMMEDIATE w_sql INTO W_VALOR;

         --substituiria as 2 linhas acima por esta
         W_VALOR := varcha2tocolumn(r.column_name);

         LINHA := LINHA || W_VALOR;
      END LOOP;

      RETURN LINHA;
   END;
Responder
  • Informação