Подтвердить что ты не робот

Использование подготовленных выражений для установки имени таблицы

Я пытаюсь использовать подготовленные инструкции для установки имени таблицы для выбора данных, но при выполнении запроса я получаю сообщение об ошибке.

Ниже приведен пример кода ошибки и примера.

[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();

Любые мысли о том, что может быть причиной этого?

4b9b3361

Ответ 1

Имя таблицы нельзя использовать в качестве параметра. Он должен быть жестко закодирован. Поэтому вы можете сделать что-то вроде:

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

Ответ 2

Это технически возможно с обходным путем, но очень плохая практика.

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

И затем, когда вы хотите выбрать из first_table, вы устанавливаете параметр с помощью

ps.setInt(1, 99);

Или, если нет, вы установите его на что-то еще.

Ответ 3

Как сказал ряд людей, вы не можете использовать параметр оператора для имени таблицы, только для переменных как часть условия.

Исходя из того факта, что у вас есть имя таблицы переменных с (по крайней мере) двумя именами таблиц, возможно, было бы лучше создать метод, который берет объект, который вы храните, и возвращает подготовленный оператор.

PreparedStatement p = createStatement(table);

Ответ 4

Это может помочь:

public ResultSet getSomething(String tableName) {

PreparedStatement ps = conn.prepareStatement("select * from \'"+tableName+"\'");
ResultSet rs = ps.executeQuery();
}

Ответ 5

Если вам нужно решение, которое не уязвимо для SQL-инъекций, вам нужно продублировать запрос для всех необходимых вам таблиц:

final static String QUERIES = {
    "SELECT x FROM Table1 x WHERE a=:a AND b=:b AND ...",
    "SELECT x FROM Table2 x WHERE a=:a AND b=:b AND ...",
    "SELECT x FROM Table3 x WHERE a=:a AND b=:b AND ...",
    ...
};

И да: запросы являются дубликатами, и отличается только имя таблицы.

Теперь вы просто выбираете запрос, который соответствует вашей таблице, например, как

...
PreparedStatement st = conn.prepareStatement(QUERIES[index]);
...

Вы можете использовать этот подход с JPA, Hibernate, что угодно...

Если вы хотите более подробный подход, подумайте об использовании перечисления типа

enum AQuery {
    Table1("SELECT x FROM Table1 x WHERE a=:a AND b=:b AND ..."),
    Table2("SELECT x FROM Table2 x WHERE a=:a AND b=:b AND ..."),
    Table3("SELECT x FROM Table3 x WHERE a=:a AND b=:b AND ..."),
    ...

    private final String query;
    AQuery(final String query) {
        this.query = query;
    }

    public String getQuery() {
        return query;
    }
}

Теперь используйте индекс

String sql = AQuery.values()[index].getQuery();
PreparedStatement st = conn.prepareStatement(sql);
...

Или используйте имя таблицы

String sql = AQuery.valueOf("Table1").getQuery();
PreparedStatement st = conn.prepareStatement(sql);
...

Ответ 6

Я не уверен, что вы можете использовать PreparedStatement для указания имени таблицы, просто значения некоторых полей. В любом случае, вы можете попробовать один и тот же запрос, но без скобок:

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

Ответ 7

String table="pass"; 

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

PreparedStatement ps=con.prepareStatement(st);

ResultSet rs = ps.executeQuery();

Ответ 8

Существует способ передать имя таблицы как переменную

Строка NameOfTable = "test.Employee";

String Fquery = "SELECT * FROM" + NameOfTable + ", где Done = 'No'";

Примечание: должно быть пространство между FROM и последующим "а также между" и где ключевое слово