2.3. SQL - Ограничение выборки

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

  • Некоторые базы данных чувствительны к регистру данных. Нет, не к операторам, а именно к данным в таблице, а значит, слово АНДРЕЙ и Андрей при сравнении будут восприниматься как разные. В MS SQL Server можно настроить – должны ли сравнительные операции для строк быть чувствительными к регистру букв;
  • Возможно, что ваша база данных может воспринимать текст только в верхнем регистре.
  • Некоторые производители отклоняются от стандартов. Даже Microsoft в разных базах данных поддерживает стандарт SQL по-разному. Например, для создание связи между таблицами в MS SQL Server есть возможность использовать ANSII SQL метод и оператор JOIN, а в MS Access работает только JOIN.

Следующий оператор, с которым я хочу вас познакомить, будет WHERE. Этот оператор задает критерии поиска. Например, нам надо выбрать все записи из таблицы tbPeoples, где в поле "vcName" содержится имя "Андрей". В этом случае необходимо написать следующий запрос:

SELECT * 
FROM tbPeoples
WHERE vcName = 'Андрей'

Если проговорить весь запрос словами, то он будет звучать так: "Выбрать все из tbPeoples, где поле vcName равно "Адрей". Еще одно замечание: в запросах, строки выделяются кавычками. В зависимости от базы данных, кавычки могут быть одинарными или двойными. Стандартом предусмотрены двойные, но в MS SQL Server используются одинарные кавычки. В стандарте для сравнения строк используется оператор LIKE, которые ставится вместо знака равенства:

SELECT * 
FROM tbPeoples
WHERE vcName LIKE 'Андрей'

В результате мы увидим одну или несколько строк, которые в поле vcName содержат имя Андрей.

Но MS SQL Server позволяет сравнивать строки знаком равенства. К тому же оператор LIKE работает медленнее, потому что позволяет использовать шаблоны, о которых мы еще поговорим.

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

SELECT * 
FROM tbPeoples
WHERE idPosition = 10

В этом случае мы производим поиск по числовому полю, поэтому используем знак равенства, а само число не нужно выделять кавычками. Но даже, если вы выделите число одинарными кавычками, ошибкой это считаться не будет, поэтому следующий запрос, также является корректным:

SELECT * 
FROM tbPeoples
WHERE idPosition = '10'

Язык SQL не жестко типизирован и основные преобразования между типами данных производятся автоматически, без нашего вмешательства. В данном случае, поле idPosition является числовым, а так как мы сравниваем его со строкой, то содержимое строки будет автоматически преобразовано к числу. Другое дело, если в вместо числа передать строку, которая будет содержать недопустимые символы, т.е. не цифры, например:

SELECT * 
FROM tbPeoples
WHERE idPosition = '10f'

В этом случае SQL сервер вернет нам ошибку:

Syntax error converting the varchar value '10f' to a column of data type int. (Синтаксическая ошибка преобразования типа varchar со значением '10f' в колонку с типом данных int).

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

Пока что мы использовали только оператор равенства. Но это не значит, что больше ничего нет. Стандарт разрешает использовать следующие операторы:

  • "=" - Равный
  • ">" - Больше
  • "<" - Меньше
  • ">=" - Больше или равно
  • "<=" - Меньше или равно
  • "<>" - Неравно

Операторы "больше", "меньше" и др. можно использовать не только с числами, но и со строками. В этом случае буква "А" будет меньше чем "Р". При сравнении строк разного регистра, меньшим оказывается строка в верхнем регистре, например, "А" будет меньше "а" и "Р" будет меньше "а". Но помните, что не всегда база данных чувствительна к регистру, это зависит от настроек.

Давайте выберем из базы данных все записи, в которых имена начинаются с буквы большей, чем буква «С»:

SELECT * 
FROM tbPeoples
WHERE vcName > 'С'

Из тестовой таблицы в результат попадут имена Сергей и Славик и Шварц. Почему Сергей и Славик попадают в результат, ведь первая буква равна С, а мы запросили слова, где строки больше чем С? Дело в том, что сравнение происходит всего слова, а имена содержать более одной буквы. Если бы имя было сокращено до одной буквы С, то такая строка не попала бы в результат, но слова с большим количеством букв попадают в результат. Это как открыть словарь, начиная с буквы «С». Сама буква не попадает в результат, но все слова, содержащие больше букв, будут отображены.

Иногда бывает необходимо вывести на экран результат запроса, но при этом он обязательно должен быть пустым. Для этого необходимо написать такое условие, которое однозначно не вернет ни одной строки. Можно выдумывать какие-то сложные сравнения в секции WHERE, но самый эффективный вариант написать:

SELECT * 
FROM tbPeoples
WHERE 1 = 0

В качестве проверки WHERE стоит условие 1 равно 0, но это условие никогда в жизни не может быть выполнено, а значит, в результате всегда не будет ни одной строки.

Когда это может понадобиться? Допустим, вы не знаете, какие поля есть в таблице и хотите их узнать. Для этого можно выполнить запрос:

SELECT * 
FROM tbPeoples

Но если в таблице tbPeoples очень много записей, то выполнение будет долгим, потому что сервер должен вернуть все строки, которые нам не нужны. Намного проще поставить условие 1=0 и результат появиться на экране мгновенно.

Если создавать программу на высокоуровневом языке, например, Delphi, то пока запрос не активен, на форме будет отображаться сетка в не очень удобном виде (без заголовков полей). Чтобы отобразить заголовки, но при этом в результате не было данных, я всегда выполняю запрос с условием 1=0. В этом случае для сервера и программы это не будет большими накладными расходами, а вот для пользователя результат будет наглядным и красивым.

Предыдущая глава

2. Transact-SQL Работа с данными

Следующая глава

2.4. SQL - Булевы операторы

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне