Java PreparedStatement жалуется на синтаксис SQL при execute () - PullRequest
3 голосов
/ 14 июня 2011

Это сводит меня с ума ... Что я здесь не так делаю?

ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
    PreparedStatement pStmt = conn.prepareStatement("ALTER TABLE testTable ADD ? varchar(100)");
        for (String s : toAdd) {
            pStmt.setString(1, s);
            pStmt.execute();
        }
} catch (SQLException e) {
    e.printStackTrace();
}

Результаты ... ... 1004 *

02: 59: 12,885 ОШИБКА [STDERR]com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: у вас есть ошибка в вашем синтаксисе SQL;проверьте руководство, соответствующее вашей версии сервера MySQL, чтобы найти правильный синтаксис для использования рядом с '' password 'varchar (100)' в строке 1

, но ...

ArrayList<String> toAdd = new ArrayList<String>();
toAdd.add("password");
try{
    Statement stmt = conn.prepareStatement();
        for (String s : toAdd) {
            stmt.execute("ALTER TABLE testTable ADD "+s+" varchar(100)");
        }
} catch (SQLException e) {
    e.printStackTrace();
}

отлично работает ... Так же как и прямой ввод текста непосредственно в клиент командной строки MySQL.

mysql> alter table testTable add stringGoesHere varchar(100);
Query OK, 1 row affected (0.23 sec)
Records: 1  Duplicates: 0  Warnings: 0

Что я делаю не так?

Ответы [ 6 ]

9 голосов
/ 14 июня 2011

В руководстве MySQL четко сказано, что ? (маркеры параметров) предназначены только для значений данных привязки, а не для имен столбцов.

Маркеры параметров можно использовать только там, гдедолжны появиться значения данных, а не для ключевых слов SQL, идентификаторов и т. д.

Поэтому вам придется использовать второй подход.

1 голос
/ 14 июня 2011

При использовании подготовленного оператора ваш параметр обрабатывается аналогично строковому литералу. В результате ваше утверждение эквивалентно «ALTER TABLE testTable ADD \ '" + s + "\' varchar (100)". Обратите внимание на одинарные кавычки вокруг имени поля в сообщении об ошибке.

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

1 голос
/ 14 июня 2011

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

1 голос
/ 14 июня 2011

Заполнители в JDBC предназначены для данных, а не для таблиц, столбцов, представлений или имен функций.И не зря.Схема БД приложения в большинстве случаев является статической и изменяется редко.Нет никаких преимуществ, делающих их динамичными.

0 голосов
/ 14 июня 2011

Попробуйте использовать следующее

pStmt.executeUpdate ();

pStmt.close ();

0 голосов
/ 14 июня 2011

Вы не можете отправить инструкцию ALTER TABLE, используя такие параметры, как этот.

Я полагаю, что нельзя выполнять операторы DDL в Java PreparedStatement.

...