Ist es möglich, Spaltennamen über Bind-Variablen in Oracle zu verweisen?
-
03-07-2019 - |
Frage
Ich versuche, einen Spaltennamen zu verweisen, eine Abfrage in einer Anwendung mit einer Oracle-Datenbank in Verbindung steht, um zu bestellen. Ich mag ein Bind-Variable verwenden, so dass ich dynamisch ändern kann, was durch die Abfrage zu bestellen.
Das Problem, das ich habe, ist, dass die Datenbank ignoriert die Reihenfolge von Spalte zu sein scheint.
Wer weiß, ob es eine bestimmte Art und Weise zu einer Datenbankspalte über einen Bind-Variable zu beziehen ist, oder wenn es überhaupt möglich?
z meine Abfrage
SELECT * FROM PERSON ORDER BY :1
(wobei :1
gebunden wird, um PERSON.NAME
)
Die Abfrage wird nicht Ergebnisse in alphabetischer Reihenfolge der Rückkehr, ich mache mir Sorgen, dass die Datenbank dies interpretiert als: -
SELECT * FROM PERSON ORDER BY 'PERSON.NAME'
, die offensichtlich nicht funktionieren.
Alle Vorschläge werden sehr geschätzt.
Lösung
Nein. Sie können keine Bind-Variablen für Tabellen- oder Spaltennamen verwenden.
Diese Informationen werden benötigt, um den Ausführungsplan zu erstellen. Ohne zu wissen, was Sie bestellen möchten, wäre es unmöglich, herauszufinden, was Index zu verwenden, zum Beispiel.
Anstelle von Bind-Variablen, haben Sie direkt die Spaltennamen in die SQL-Anweisung zu interpolieren, wenn Ihr Programm schafft. Unter der Annahme, dass Sie Vorkehrungen gegen SQL-Injection, gibt es keinen Nachteil, dass.
Update: Wenn Sie wirklich durch Reifen springen wollen, könnten Sie wahrscheinlich so etwas wie
order by decode(?, 'colA', colA, 'colB', colB)
, aber das ist einfach albern. Und langsam. Dies nicht tun.
Andere Tipps
Wie Sie JDBC verwenden. Sie können den Code, um etwas ohne Bind-Variablen neu schreiben. Auf diese Weise kann auch dynamisch den Auftrag ändern, indem Sie z.
String query = "SELECT * FROM PERS ";
if (condition1){
query = query+ " order by name ";
// insert more if/else or case statements
} else {
query = query+ " order by other_column ";
}
Statement select = conn.createStatement();
ResultSet result = select.executeQuery(query);
oder auch
String columnName = getColumnName(input);
Statement select = conn.createStatement();
ResultSet result = select.executeQuery("SELECT * FROM PERS ORDER BY "+columnName);
ResultSet result = select.executeQuery ( "SELECT * FROM PERS ORDER BY" + column);
wird immer eine neue Anweisung an die Datenbank sein. Das heißt, es ist, wie Thilo bereits erklärt, unmöglich „Nachbestellung“ eine bereits gebunden ist, berechnet, vorbereitet, analysierte Anweisung. Wenn dieses Ergebnis mit über und über in Ihrer Anwendung und das einzige, was gesetzt, was im Laufe der Zeit ändert, wird die Reihenfolge der Präsentation, versuchen, den Satz in Ihrem Client-Code zu bestellen. Andernfalls dynamischer SQL ist in Ordnung, aber kommt mit einem großen Platzbedarf.