Вопрос-ответ

Variable column names using prepared statements

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

Мне было интересно, есть ли какой-либо способ указать возвращаемые имена столбцов с помощью подготовленных инструкций.

Я использую MySQL и Java.

Когда я попробую это:

String columnNames="d,e,f"; //Actually from the user...
String name = "some_table"; //From user...
String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//...
stmt = conn.prepareStatement(query);
stmt.setString(1, columnNames);
stmt.setString(2, "x");

Я получаю этот тип инструкции (печать непосредственно перед выполнением).

SELECT a,b,c,'d,e,f' FROM some_table WHERE d='x'

Однако я хотел бы видеть:

SELECT a,b,c,d,e,f FROM some_table WHERE d='x'

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

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

Переведено автоматически
Ответ 1

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

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

Если вы хотите продолжить в этом направлении, вам необходимо очистить имена столбцов (чтобы избежать SQL-инъекции) и объединить / создать SQL-строку самостоятельно. Заключите в кавычки отдельные имена столбцов и используйте String#replace() для экранирования той же кавычки внутри имени столбца.

Ответ 2

Подготовьте белый список разрешенных имен столбцов. Используйте "запрос", чтобы посмотреть, есть ли в белом списке имя столбца. Если нет, отклоните запрос.

Ответ 3

Для подготовленных инструкций MySQL с NodeJS (mysqljs / mysql) вам нужно знать, что ? это для значений, но если вам нужно экранировать имена столбцов, таблицы и т.д., используйте ?? вместо этого.

Что-то вроде этого будет работать:

SELECT ??, ??, ?? FROM ?? WHERE ?? < ? 

Установите значения в ['id', 'name', 'address', 'user', 'id', 100]

Ответ 4

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

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

java sql jdbc