2012-03-27 8 views
0

I in Spalten mit Parametern, aber Tabellennamen, Spaltennamen, etc., so habe ich versucht, diese Werte nicht nur gespeichert ersetzen wollte:Der Versuch, eine etwas allgemeine Abfragemethode erstellen

// Can get any string value based on any string key with this function 
    public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) { 
     String qry = "SELECT :ColOfInterest FROM :TableToQuery WHERE :KeyValColumn = :KeyVal"; 
     OracleCommand cmd = new OracleCommand(qry, con); 
     cmd.CommandType = CommandType.Text; 
     OracleParameter opColOfInterest = cmd.Parameters.Add("ColOfInterest", OracleDbType.Varchar2, 
      AColumnToReturn, ParameterDirection.Input); 
     OracleParameter opTableToQuery = cmd.Parameters.Add("TableToQuery", OracleDbType.Varchar2, 
      ATable, ParameterDirection.Input); 
     OracleParameter opKeyValColumn = cmd.Parameters.Add("KeyValColumn", OracleDbType.Varchar2, 
      AColumnToQuery, ParameterDirection.Input); 
     OracleParameter opKeyVal = cmd.Parameters.Add("KeyVal", OracleDbType.Varchar2, 
      AKeyVal, ParameterDirection.Input); 
     return cmd.ExecuteScalar().ToString(); 
    } 

... aber So erhalten, "ORA-00903 invalid table name"

, versuchte ich in der C# Art und Weise tun:

public string GetValForKeyVal(string ATable, string AKeyVal, string AColumnToQuery, string AColumnToReturn) { 
     String qry = String.Format("SELECT {0} FROM {1} WHERE {2} = {3}", AColumnToReturn, ATable, AColumnToQuery, AKeyVal); 
     OracleCommand cmd = new OracleCommand(qry, con); 
     cmd.CommandType = CommandType.Text; 
     return cmd.ExecuteScalar().ToString(); 
    } 

... aber das auch nicht weiter, und zwar mit, "ORA-00904 "WHYAMINOTQUOTINGTHEDOT"."EXE": invalid identifier"

Banne ich den falschen Baum an oder benutze den falschen Weg, um eine Katze zu fangen?

In alten Zeiten (Delphi), könnten Sie eine Zeichenfolge für die Übergabe an die DB-Engine sicher machen, indem Sie es in etwas wie QueryStr() umschließen. Gibt es eine analoge Hilfsfunktion für C#/Oracle?

Antwort

4

Sie können keine Parameter verwenden, um Tabellennamen und Spaltennamen in Oracle zu ersetzen. Einer der Hauptvorteile der Verwendung von parametrisierten Abfragen aus der Datenbankperspektive besteht darin, dass Oracle die Abfrage einmal parsen kann (unter anderem den Abfrageplan generieren) und sie dann mehrmals mit unterschiedlichen Parameterwerten ausführen kann. Wenn sich die Tabelle oder die Spalten ändern, erfordert dies ein neues hartes Parsen der Abfrage, so dass sie nicht als Bindevariable geeignet wäre.

Können Sie etwas mehr über das Problem erklären, das Sie lösen möchten? Es scheint ungewöhnlich, dass Sie Code schreiben möchten, der eine beliebige Spalte einer beliebigen Tabelle abfragen könnte - was im Allgemeinen bedeutet, dass Sie eine Reihe von verschiedenen Tabellen haben, die die gleiche grundlegende Art von Daten speichern. In diesem Fall wären Sie im Allgemeinen besser gedient, indem Sie die Normalisierung Ihres Datenmodells wieder besuchen. Wenn Sie ermitteln möchten, ob ein bestimmter Tabellenname oder Spaltenname aus SQL-Injection-Sicht sicher an die Datenbank übergeben werden soll, können Sie DBMS_ASSERT package verwenden, aber zu diesem Zeitpunkt ist es möglicherweise besser, ALL_TAB_COLUMNS für den angegebenen Tabellennamen und die angegebene Spalte abzufragen Name, um zu sehen, ob es tatsächlich Spalten AColumnToReturn und AColumnToQuery in ATable in der Datenbank gibt.

+0

Das erneute Besuchen der DB-Struktur ist keine Option. In der Vergangenheit habe ich "generische" Abfragen geschrieben, wo ich ein int übergeben und eine Zeichenfolge erhalten kann, und umgekehrt; es reduziert die Notwendigkeit, nur noch eine Reihe von Abfragen zu schreiben. Quirky, gewährt, aber es erfüllt sich mit meiner Zufriedenheit. –

Verwandte Themen