2009-07-30 5 views
22

Próbuję użyć przygotowanych instrukcji, aby ustawić nazwę tabeli, z której będą wybierane dane, ale nadal otrzymuję błąd podczas wykonywania zapytania.Używanie gotowych instrukcji do ustawiania nazwy tabeli

Błąd i przykładowy kod są wyświetlane poniżej.

[Microsoft][ODBC Microsoft Access Driver] Parameter 'Pa_RaM000' specified where a table name is required. 



private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [?]"; //?=date 
public Execute(String reportDate){ 
    try { 

     Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
     Connection conn = DriverManager.getConnection(Display.DB_MERC); 
     PreparedStatement st = conn.prepareStatement(query1); 
     st.setString(1, reportDate); 
     ResultSet rs = st.executeQuery(); 

Jakieś myśli o tym, co może być przyczyną tego?

+0

Tak, sanityzacja danych wejściowych, aby zapobiec zastrzykom SQL! –

+1

Jeśli chcesz zastąpić różne nazwy tabel w kwerendzie o tej samej strukturze, wskazuje to na lukę w projekcie bazy danych. Przynajmniej wskazuje na wiele tabel o tych samych atrybutach relacji. Normalizuj go do pojedynczej tabeli z kolumną "temat". –

Odpowiedz

29

Nazwa tabeli nie może być używana jako parametr. Musi być mocno zakodowany. Więc można zrobić coś takiego:

private String query1 = "SELECT plantID, edrman, plant, vaxnode FROM [" + reportDate + "?]"; 
+0

Ok dzięki, zgadnij, po prostu użyj zastępczego ciągu znaków Zaakceptowano odpowiedź jako odpowiedź Dzięki! – Brandon

+4

Nie! Jest to problem związany z wtyczką SQL. – Benvorth

+7

użyj 'org.apache.commons.lang.StringEscapeUtils.escapeSql' na nazwie tabeli, aby upewnić się, że nie narażasz schematu na ryzyko. – Sebas

-2

Nie jestem pewien, można użyć PreparedStatement podać nazwę tabeli, tylko wartości niektórych pól. W każdym razie, można spróbować tego samego zapytania, ale bez nawiasów:

"SELECT plantID, edrman, plant, vaxnode FROM ?" 
+0

Potrzebne są nawiasy, aby uciec "/" w zapytaniach ... lub może to być data. Sprawdziłem to latem ubiegłego roku. – Brandon

-2
String table="pass"; 

String st="select * from " + table + " "; 

PreparedStatement ps=con.prepareStatement(st); 

ResultSet rs = ps.executeQuery(); 
+1

Czy możesz podać kontekst swojej odpowiedzi, w ten sposób przyszli czytelnicy będą mogli nauczyć się, jak zastosować ją w swoich problemach, a nie tylko w tej sytuacji. – Newd

+4

Podatny na iniekcję SQL. Nie rób tego! –

-3

Jest sposób przekazać nazwę tabeli jako zmienna

String NameOfTable = „test.Employee”;

String Fquery = "SELECT * FROM" + NameOfTable + "gdzie Done =" Nie "";

Uwaga: powinna istnieć przestrzeń pomiędzy OD a sukces „a także między” i gdzie kluczowych

+4

Podatny na iniekcję SQL. Absolutnie NIE odpowiedź! –

0

Jak wiele osób mówi, nie można użyć parametru oświadczenie o nazwę tabeli, tylko dla zmiennych jako części warunku.

Na podstawie tego, że posiadasz nazwę tabeli zmiennej z (co najmniej) dwiema nazwami tabel, być może najlepiej byłoby stworzyć metodę, która pobiera przechowywany obiekt i zwraca przygotowaną instrukcję.

PreparedStatement p = createStatement(table); 
1

Jest to technicznie możliwe z obejściem, ale bardzo złą praktyką.

String sql = "IF ? = 99\n"; 
sql += "SELECT * FROM first_table\n"; 
sql += "ELSE\n"; 
sql += "SELECT * FROM second_table"; 
PreparedStatement ps = con.prepareStatement(sql); 

I wtedy, gdy chcemy wybrać z first_table ustawić parametr

ps.setInt(1, 99); 

lub jeśli nie można ustawić go na coś innego.