Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Ist es möglich, den Tabellennamen als Parameter in Oracle zu übergeben?

Sie haben mehrere unterschiedliche Tabellen mit exakt gleichen Spaltennamen und Datentypen? Riecht nach einem zwielichtigen Design.

Wie auch immer, wir können Variablen nicht als Datenbankobjekte in einfachem SQL verwenden. Wir müssen dynamisches SQL verwenden.

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;

Ein Grund, die Verwendung von dynamischem SQL zu vermeiden, besteht darin, dass es für Missbrauch anfällig ist. Böswillige Personen können die Parameter verwenden, um zu versuchen, unsere Sicherheit zu umgehen. Dies wird als SQL-Injection bezeichnet. Ich denke, die Leute überschätzen die Bedeutung der SQL-Injektion. Es ist nicht automatisch eine Bedrohung. Wenn die Prozedur beispielsweise eine private Prozedur in einem Paket ist (d. h. nicht in der Spezifikation deklariert ist), ist es unwahrscheinlich, dass jemand sie kapern wird.

Aber es ist sinnvoll, Vorkehrungen zu treffen. DBMS_ASSERT ist ein Paket, das in Oracle 10g eingeführt wurde, um versuchte SQL-Injection-Angriffe abzufangen. In diesem Fall würde es sich lohnen, es zu verwenden, um den übergebenen Tabellennamen

zu validieren
....
'UPDATE '|| DBMS_ASSERT.simple_sql_name(pADSLTable)
....  

Dies würde verhindern, dass jemand 'pay_table set salary = salary * 10 where id = 1234 --' übergibt als Parameter für den Tabellennamen.

Ein weiterer Grund, dynamisches SQL zu vermeiden, ist, dass es schwieriger ist, es richtig zu machen und schwieriger zu debuggen. Die Syntax der eigentlichen Anweisung wird erst zur Laufzeit überprüft. Es ist gut, über eine vollständige Suite von Komponententests zu verfügen, die alle übergebenen Eingaben validieren, um sicherzustellen, dass die Prozedur keine Syntaxausnahme auslöst.

Schließlich wird solches dynamisches SQL nicht in Ansichten wie ALL_DEPENDENCIES angezeigt. Dies macht es schwieriger, eine Auswirkungsanalyse durchzuführen und alle Programme zu finden, die eine bestimmte Tabelle oder Spalte verwenden.