Переменные имена столбцов с использованием подготовленных операторов
Мне было интересно, если в любом случае указывать имена возвращенных столбцов, используя подготовленные операторы.
Я использую 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
values
Если вы хотите продолжить в этом направлении, вам необходимо дезинформировать имена столбцов и самостоятельно объединить/построить строку SQL. Напишите отдельные имена столбцов и используйте String#replace()
, чтобы избежать той же цитаты внутри имени столбца.
Ответ 2
Подготовьте белый список разрешенных имен столбцов. Используйте "запрос" для поиска в белом списке, чтобы увидеть, есть ли имя столбца. Если нет, отклоните запрос.
Ответ 3
Я думаю, что этот случай не может работать, потому что вся точка подготовленного оператора состоит в том, чтобы помешать пользователю вставлять неэкранированные биты запроса - так что вы всегда будете иметь текст, цитируемый или экранированный.
Вам необходимо очистить этот ввод в Java, если вы хотите безопасно влиять на структуру запроса.
Ответ 4
Ниже приведено решение в java.
String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
Ответ 5
Использовать недостаток использования sql в интерфейсе Statement как преимущество.
Пример:
st=conn.createStatement();
String columnName="name";
rs=st.executeQuery("select "+ columnName+" from ad_org ");
Ответ 6
public void MethodName(String strFieldName1, String strFieldName2, String strTableName)
{
//Code to connect with database
String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
st=conn.createStatement();
rs=st.executeQuery(strSQLQuery);
//rest code
}