Подумал тут не давно, что может не обязательно писать большие статьи. Может писать о мелочах. Существует куча тонких моментов с которыми приходится сталкивать в работе. Сначала ты на эти мелкие камни преткновения тратишь кучу времени. Потому как не знаешь как их исправить. А так как вроде это мелочь, такие моменты мало кто освещает. И редкий новичок осознает все множество подводных камней и не документированных возможностей систем.
Раньше при разработке новой функции в проекте или в начале нового проекта, я особо не задумывался над мелкими моментами. Но практика показала зря…
Например, при проектировании базы данных под свое приложение, я не учитывал особенности построения индексов, применения справочников, особенностей хранения данных и многое другое. Как результат, потратил много времени на оптимизацию и поиск решений обхода не продуманной заранее структуры.
Публиковать такие мини-статьи я буду в разделе “Разные мелочи”.

Теория…

Думаю достаточно лирического отступления и перейдем собственно к практике. Сегодня мне хотелось бы написать про такую мелочь, как функция CONCAT в Mysql.
Функция CONCAT применяется в для объединения нескольких строк в одну. В качестве аргументов и передаются сроки которые нужно объединить.
Пример:
SELECT CONCAT(‘My’,’Sql’,’-GOOD!!!’) as STR

Результат:

[table id=7 /]

CONCAT — объединяет все строки перечисленные через ‘,’;
Конструкция ‘as STR’ применяется для того чтобы задать произвольное имя поля, в которое будет выдан в результат работы функции.

История…

Я писал сохраненную функцию, задача которой объединять значения несколько полей и выводить в одну строчку. Поля Фамилия,Имя, Отчество, Серия документа, Номер документа, Дата выдачи документа, Кто (поле принимает одно из трех значений “ОТЦЕ”,”МАТЬ”,”ИНОЕ”).
Результатом работы функции была строка вида: “ФАМИЛИЯ ИМЯ ОТЧЕСТВО СЕРИЯ ДОК. № НОМЕР ДОК. КТО”.
Все написал и вроде работало отлично. Но из-за того, что проект не всегда стабильно работал, еще и многое просто “руками” правили, в базе существовали записи, где поле “КТО” было заполнено как NULL.
И вот я столкнулся с такой проблемой: так как я все объединял одной конструкцией CONCAT, то для выше описанных строк на выходе она выдала мне NULL . То есть, если хоть один аргумент функции будет равен NULL — результат автоматические будет NULL.
Как я и говорил это мелочь, но если не учитывать эту мелочь можно нарваться на серьезные грабли при дальнейшей обработки информации.

Решение проблемы…

Есть два пути решения проблемы:
1.Применения аналога функции CONCAT, это CONCAT_WS. Суть работы та же — объединить строки разделенные ‘,’. Да только если какой-нибудь аргумент равен NULL, то функция просто игнорирует этот аргумент и продолжает свою работу. Применение: возвращаясь к нашему примеру ФИО, поле “Отчество” может быть не всегда заполнено. В результате на месте отчества в получаемой строке будет два пробела.
Можно избежать этой ситуации, для этого в поле “Отчество ” по умолчанию выставляем значение NULL. И пользуясь выше описанной функцией, при отсутствии значения в поле, оно будет игнорироваться, а мы на выходе получим красивую строчку.
2. Второй вариант решения проблемы, это применения функции IFNULL (values1,values2). Суть метода проста: функция IFNULL выполняет следующие преобразование: если values1 <> NULL — то в результат передается значение values1, если равно NULL — то в результат передается values2. Сейчас покажу все на примере.
Пример: Объедением три поля “Фамилия”, “Имя”, “Отчество” (последние поле по умолчанию заполняется NULL). Что бы функция CONCAT отработала корректно, для записей где отчество отсутствует, применим IFNULL.
Пример запроса: SELECT CONCAT(FAM,’ ’,IM,’ ’,IFNULL(OT,’’)) as STR

Результат:

[table id=8 /]

В результате получаем строку ‘Иванов Иван’. В записи отсутствовало значение в поле “Отчество”, но мы не получили в результате NULL, потому что отработала функция IFNULL и она вернула переменную values2 (для первого случая). Если значение было бы не пустое — вернется значение поля “Отчества” (для второго случае).

Читайте, применяйте и комментируйте. С уважением, ваш Shinobi.

P.S. Нравится материал. Делитесь в твитере, лайкайте в контакте и так далее. Хочется выразить благодарность — кликай по рекламе. Все спасибо))

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте как обрабатываются ваши данные комментариев.