Я видел запрос, выполняемый в файле журнала в приложении. и он содержал запрос типа:
SELECT ID FROM CUST_ATTR49 WHERE 1=0
что такое использование такого запроса, который не должен ничего возвращать?
Я видел запрос, выполняемый в файле журнала в приложении. и он содержал запрос типа:
SELECT ID FROM CUST_ATTR49 WHERE 1=0
что такое использование такого запроса, который не должен ничего возвращать?
Подобный запрос можно использовать для проверки базы данных. Пункт:
WHERE 1=0
Обеспечивает отправку неданных, поэтому плата ЦП не взимается, нет сетевого трафика или другого ресурса.
Подобный запрос может протестировать:
WHERE 1=0 OR <condition>
)Я могу думать о том, что у вас есть форма фильтра, в которой вы не хотите иметь никаких результатов поиска. Если вы укажете какой-то фильтр, они будут добавлены в предложение where.
Или он обычно используется, если вам нужно создать запрос sql вручную. Например. вы не хотите проверять, является ли предложение where пустым или нет.. и вы можете просто добавить такие вещи, как это:
where := "WHERE 0=1"
if X then where := where + " OR ... "
if Y then where := where + " OR ... "
(если вы связываете предложения с OR, вам нужно 0 = 1, если у вас есть И у вас есть 1 = 1)
Это может также использоваться для извлечения схемы таблицы из таблицы без извлечения каких-либо данных внутри этой таблицы. Как сказал Андреа Коллени, это будут другие преимущества использования этого.
цитируется у Грега
Если список условий неизвестен во время компиляции и вместо этого построенный во время выполнения, вам не нужно беспокоиться о том, есть ли у вас один или более одного условия. Вы можете создать их все как:
и
и объединить их все вместе. При первом запуске 1 = 1 initial и с чем-то ассоциироваться.
Я никогда не видел, чтобы это использовалось для любой защиты от инъекций, поскольку вы говорят, что это не похоже на то, что это очень поможет. Я видел, как он использовался как осуществление удобный. Механизм запросов SQL в конечном итоге игнорирует 1 = 1, поэтому он не должен иметь никакого влияния на производительность.
Почему кто-то использует WHERE 1 = 1 AND <conditions> в предложении SQL?
Некоторые системы используют сценарии и могут динамически устанавливать выбранные записи для скрытия из полного списка; поэтому для SQL необходимо передать ложное условие. Например, три записи из 500 могут быть отмечены как конфиденциальность по медицинским причинам и не должны быть видны всем. Динамический запрос будет контролировать 500 записей, которые видны тем, кто находится в HR, а 497 видны менеджерам. Значение будет передано в предложение SQL, которое условно установлено, то есть "WHERE 1 = 1" или "WHERE 1 = 0", в зависимости от того, кто зарегистрирован в системе.
Если пользователь намеревается только добавлять записи, то самый быстрый метод открывает набор записей без возврата каких-либо существующих записей.
В качестве ответа, а также в качестве дополнительного разъяснения к тому, что @AndreaColleoni уже упомянул:
управлять многими условиями ИЛИ в динамических запросах (например,
WHERE 1=0 OR <condition>
)
Я использую это как оператор переключения (вкл/выкл) для части моего запроса.
Если бы я должен был использовать
WHERE (0=? OR first_name = ?) AND (0=? OR last_name = ?)
Затем я могу использовать первую переменную связывания (?
), Чтобы включить или выключить критерий поиска first_name
. и третья переменная связывания (?
) для включения или выключения критерия last_name
.
Только для этих двух критериев это не кажется полезным, так как, возможно, проще сделать то же самое, динамически создавая условие WHERE, либо указав только first_name
или last_name
, либо оба, либо ни одного. Таким образом, ваш код должен будет динамически создавать 4 версии одного и того же запроса. Представьте себе, что произойдет, если у вас будет 10 различных критериев, а затем, сколько комбинаций одного и того же запроса вам придется обрабатывать?
Я также мог бы добавить, что добавление в 0 =? так как переменная связывания не будет работать очень хорошо, если все ваши критерии проиндексированы. Оптимизатор времени выполнения, который выберет соответствующие индексы и планы выполнения, может просто не увидеть экономической выгоды от использования индекса в этих немного более сложных предикатах. Поэтому я обычно советую вводить 0/1 явно в ваш запрос (конкатенация строк в вашем sql или поиск/замена). Это даст компилятору возможность оптимизировать избыточные операторы и даст исполнителю времени выполнения гораздо более простой запрос для просмотра.
(0=1 OR cond = ?) --> (cond = ?)
(0=0 OR cond = ?) --> Always True (ignore predicate)
Во втором приведенном выше утверждении компилятор знает, что он никогда не должен даже учитывать вторую часть условия (cond =?
), И он просто удалит весь предикат. Если бы это была переменная связывания, компилятор никогда бы этого не достиг.
Поскольку вы просто и принудительно вводите 0/1, вероятность инъекции SQL равна нулю.
В моем SQL, в качестве одного из подходов, я обычно размещаю свои SQL-точки вставки как $ {literal_name}, а затем просто ищу/заменяю с помощью регулярного выражения любое вхождение $ {...} с соответствующим литералом, прежде чем я даже позволю компилятору нанести удар Это в основном приводит к тому, что запрос хранится следующим образом:
WHERE 1=1
AND (0=${cond1_enabled} OR cond1 = ?)
AND (0=${cond2_enabled} OR cond2 = ?)
Выглядит хорошо, легко понимается, компилятор хорошо с этим справляется, а оптимизатор на основе затрат времени выполнения понимает его лучше и будет иметь более высокую вероятность выбора правильного индекса.
Я уделяю особое внимание тому, что я делаю инъекцией. Первичным способом передачи переменных является и остается связывание переменных по всем очевидным причинам.
Это может быть полезно, когда в приложении требуются только метаданные таблицы. Например, если вы пишете приложение JDBC и хотите получить размер отображения столбцов в таблице.
Вставить фрагмент кода здесь
String query = "SELECT * from <Table_name> where 1=0";
PreparedStatement stmt = connection.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
ResultSetMetaData rsMD = rs.getMetaData();
int columnCount = rsMD.getColumnCount();
for(int i=0;i<columnCount;i++) {
System.out.println("Column display size is: " + rsMD.getColumnDisplaySize(i+1));
}
Здесь наличие запроса типа "выбрать * из таблицы" может вызвать проблемы с производительностью, если вы имеете дело с огромными данными, потому что он попытается извлечь все записи из таблицы. Вместо этого, если вы предоставите запрос типа "выбрать * из таблицы, где 1 = 0 ", он будет получать только метаданные таблицы, а не записи, поэтому он будет эффективен.
Для пользователя milso в другом потоке, другая цель для "WHERE 1 = 0":
CREATE TABLE New_table_name как выберите * FROM Old_table_name WHERE 1 = 2;
это создаст новую таблицу с той же схемой, что и старая таблица. (Очень удобно, если вы хотите загрузить некоторые данные для сравнения)
Это очень хорошо при извлечении метаданных и делает вещь общей. У многих БД есть оптимизатор, поэтому они не будут его выполнять, но он все еще является допустимым оператором SQL и должен выполняться на всех БД. Это не приведет к получению какого-либо результата, но вы знаете, что имена столбцов действительны, типы данных и т.д. Если он не выполняется, вы знаете, что с БД что-то не так (не работает и т.д.). Многие универсальные программы выполняют этот фиктивный оператор для тестирования и выборки метаданных.,
Кажется, что кто-то пытается взломать вашу базу данных. Похоже, кто-то попробовал инъекцию mysql. Подробнее об этом можно прочитать здесь: Mysql Injection