Распространенные ошибки SQL в хранимых процедурах и запросах
@data_analysis_ml - аналитика данных.
Распространенные ошибки SQL в хранимых процедурах и запросах
Я не буду описывать совсем банальные вроде ошибки синтаксиса (talbe вместо table). Рассмотрим досадные ошибки sql server, которые снижают скорость нашей разработки:
1. Ключевые слова в именах
Например, у вас есть поле Key. Его нужно заключать обязательно в скобки
select Name from @table where [Key]='code1'
2. Проблемы при приведении типов
Лучше явно приводить типы в запросах через cast и convert
select cast(itemID as nvarchar) + ' ' + name from @table
В случае, если у вас разнородная таблица (поле itemID может быть как строкой, так и числом), то для избежания исключения в запросе рекомендуется использовать try_cast или try_convert
3. Неверно поставленные скобки в условиях
select * from @table where @visible =1 and (isVisible=1 or @visible=0)
Лучше явно выделить условия скобками, чтобы было проще читать (даже, если приоритет операций не требует этого, как в этом случае).
select * from @table where (@visible =1 and isVisible=1) or @visible=0
4. Ошибка сравнения с NULL полями
Если вы сравниваете null bit поле с false, то нужно делать это аккуратно.
Такое сравнение корректно:
select * from @table where isVisible=1
Такое сравнение некорректно:
select * from @table where isVisible=0
Дело в том, что оно не учитывает что поле может быть null (а следовательно в бизнес-логике это видимость равно false)
Правильный вариант:
select * from @table where isnull(isVisible, 0)=0
Также будьте аккуратны с NULL и использованием оператора NOT IN (). Рассмотрите вариант использования Exists
5. При группировке использование полей в select или order, которые не участвуют в группировке
Вы можете использовать либо поля, по которым идет группировка, либо агрегирующие данные.
Ошибочный пример:
select code, name, count(*) from table1 group by code
6. Путаница с порядком ключевых слов в select
Используйте правильный порядок
select from (join) where group by having order by
7. Страсть к join, left join
Если вам нужно вытянуть 1 поле из соседней таблицы, то используйте подзапросы. Чтобы запрос работал быстро, вам нужно как можно быстрее отсечь ненужные данные. Если вы делаете объединение несколько больших таблиц, в итоге у вас получается большая масса данных по которым затем идет фильтрация.
Выберите сначала данные из одной таблицы, для отобранных данных уже через подзапрос в select можно достать все дополнительные данные.
select id, (select name from cats where id = catID) catName from products
8. Дубли имен в select при join
Ошибка SQL запроса:
select id, name from products inner join cats on product.catID = cats.id
Проблема в том что id есть в обоих таблицах.
Необходимо указать точнее
select products.id, products.name from products inner join cats on product.catID = cats.id
9. Умеренно используйте функции в Where
Если вы используете функции Datepart или подобные, то вероятно это приведет к тому, что индексы на используемых полях не будут задействованы в запросе (что плохо для производительности).
По возможности переделайте запрос так, чтобы можно было обойтись минимумом функций в where.
10. Подзапрос вернул несколько значений
Бывает так, что вы ожидаете, что ваш подзапрос должен вернуть одно значение. Но потом бизнес-логика и структура БД меняется, и ваш запрос может уже возвращать несколько значений и будет появляться исключение.
Можно подстраховаться и поставить в подзапросе top 1. В этом случае вы гарантированно получите максимум 1 значение.
11. Конкатенация строк с NULL
В итоге вы получите NULL для всех строки.
Если вы формируете большую строку в SELECT, то используйте функции NULLIF(col, defValue). Если колонку будет NULL, то функция подставить значение по умолчанию (например, пустую строку) и вся ваша большая формируемая строка не будет NULL.
select name + '' + nullif(descriotion, '') from products