Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

É possível passar o nome da tabela como parâmetro no Oracle?


Você tem várias tabelas diferentes com exatamente os mesmos nomes de coluna e tipos de dados? Cheira como um design desonesto.

De qualquer forma, não podemos usar variáveis ​​como objetos de banco de dados em SQL simples assim. Temos que usar SQL dinâmico.
PROCEDURE P_CUSTOMER_UPDATE
  (
      pADSLTable IN USER_TABLES.table_name%type,
      pAccountname IN NVARCHAR2,
      pStatus IN NUMBER,
      pNote IN NVARCHAR2,
      pEmail IN NVARCHAR2,
      pMobi IN NVARCHAR2,
      pServiceTypeID IN NUMBER,
      pDate IN DATE
  )
  IS
  BEGIN
      execute immediate 
          'UPDATE '||pADSLTable
          ||' SET STATUS = :1, NOTE = :2, EMAIL = :3, MOBI = :4, SERVICETYPE_ID = :5, ACTIVATION_DATE = :6'
          ||' WHERE ACCOUNT_NAME = :7'
      using pStatus, pNote, pEmail, pMobi, pServiceTypeID, pDate, pAccountname;
  END;

Uma razão para evitar o uso de SQL dinâmico é que ele está sujeito a abusos. Pessoas mal-intencionadas podem usar os parâmetros para tentar burlar nossa segurança. Isso é chamado de injeção de SQL. Acho que as pessoas superestimam o significado da injeção de SQL. Não é automaticamente uma ameaça. Por exemplo, se o procedimento for um procedimento privado em um pacote (ou seja, não declarado na especificação), é improvável que alguém o sequestre.

Mas é sensato tomar precauções. DBMS_ASSERT é um pacote introduzido no Oracle 10g para interceptar tentativas de ataques de injeção de SQL. Nesse caso valeria a pena usá-lo para validar o nome da tabela passada
....
'UPDATE '|| DBMS_ASSERT.simple_sql_name(pADSLTable)
....  

Isso evitaria que alguém passasse 'pay_table set salary = salary * 10 where id = 1234 --' como o parâmetro do nome da tabela.

Outra razão para evitar o SQL dinâmico é que é mais difícil acertar e mais difícil de depurar. A sintaxe da instrução real é verificada apenas em tempo de execução. É bom ter um conjunto completo de testes de unidade que validem todas as entradas passadas, para garantir que o procedimento não lance uma exceção de sintaxe.

Por fim, esse SQL dinâmico não aparece em visualizações como ALL_DEPENDENCIES. Isso dificulta a análise de impacto e a localização de todos os programas que usam uma determinada tabela ou coluna.