MySQL Функції: рядкові, числові, визначені користувачем, збережені

⚡ Розумний підсумок

MySQL Функції перетворюють дані перед їх збереженням або отриманням, повертаючи один обчислений результат. У цій статті пояснюються вбудовані рядкові, числові та функції дати, а також показано, як збережені та визначені користувачем функції розширюють можливості самого механізму баз даних.

  • 🔤 Функції для роботи з рядками: UCASE, LCASE та CONCAT змінюють форму тексту під час запиту; призначають обчислений стовпець псевдонімом AS, щоб результуючий набір містив читабельний заголовок.
  • 🔢 Числовий Operaторс: DIV виконує цілочисельне ділення, / повертає десяткову частку, а % (або MOD) повертає залишок від ділення.
  • 📅 Функції дати: DATE_FORMAT перетворює збережене значення YYYY-MM-DD у будь-який шаблон відображення, наприклад %d-%m-%Y, без зміни жодного рядка коду програми.
  • 🛠️ Збережені функції: CREATE FUNCTION реєструє логіку повторного використання всередині сервера; оголошуйте її як NOT DETERMINISTIC щоразу, коли тіло викликає CURDATE() або NOW().
  • ️ Функції, визначені користувачем: Зовнішні процедури, написані на C або C++ компілюються на сервері та потім поводяться точно так само, як і нативні функції.
  • ???? Вплив на продуктивність: Перенесення обчислень у базу даних усуває дублікат логіки з кожної клієнтської програми та зменшує кількість мережевих циклів обробки.

Які MySQL Функції?

MySQL може робити набагато більше, ніж просто зберігати та отримувати дані. Це також може виконувати маніпуляції з даними перед тим, як отримати або зберегти його. Саме там MySQL І тут на допомогу приходять функції. Функції — це просто фрагменти коду, які виконують операцію, а потім повертають результат. Деякі функції приймають параметри, а інші — жодного.

Давайте коротко розглянемо приклад. За замовчуванням, MySQL зберігає типи даних дати у форматі «РРРР-ММ-ДД». Припустимо, що ми створили застосунок, і наші користувачі хочуть, щоб дата поверталася у форматі «ДД-ММ-РРРР». Ми можемо використовувати MySQL вбудована функція DATE_FORMAT для досягнення цього. DATE_FORMAT є однією з найчастіше використовуваних функцій у MySQL, і ми розглянемо це детальніше пізніше в цьому уроці.

Якого б типу не була функція завжди повертає одне значення, може приймати нуль або більше параметрів у дужках, і можна використовувати будь-де, де дозволено вираз — у списку SELECT, реченні WHERE або реченні ORDER BY.

Навіщо використовувати MySQL Функції?

Тепер, коли ми знаємо, що таке функція, наступне питання: чому ми взагалі повинні завантажувати цю роботу в базу даних.

Навіщо використовувати MySQL Функції

Як показано на діаграмі вище, функція приймає вхідне значення, застосовує логіку всередині механізму бази даних і передає один результат кожній програмі, яка його запитує.

Програмісти можуть думати: «Навіщо взагалі морочитися з MySQL Функції? Цього ж ефекту можна досягти за допомогою скриптової або програмної мови». Це правда, що ми можемо досягти цього, написавши процедуру в прикладній програмі.

Повертаючись до нашого прикладу з DATE, щоб наші користувачі отримали дані в потрібному форматі, бізнес-рівень повинен сам виконати необхідну обробку.

Це стає проблемою, коли програму потрібно інтегрувати з іншими системами. Коли ми використовуємо MySQL такі функції, як DATE_FORMAT, ця функціональність вбудована в базу даних, і будь-яка програма, якій потрібні дані, отримує їх у потрібному форматі. Це зменшує переробку бізнес-логіки та зменшує невідповідності даних.

Ще одна причина для розгляду MySQL функцій полягає в тому, що вони можуть допомогти зменшити мережевий трафік у клієнт-серверних додаткахБізнес-рівню потрібно лише викликати збережену функцію, не перетягуючи необроблені рядки через мережу для маніпулювання ними. В середньому, використання функцій може значно покращити загальну продуктивність системи.

Види MySQL Функції

Визначившись з питаннями «що» та «чому», тепер ми можемо розглянути три сімейства функцій. MySQL пропонує: вбудовані функції, збережені функції та функції, визначені користувачем.

Вбудовані функції

MySQL постачається з низкою вбудованих функцій — функцій, які вже реалізовані в MySQL сервер. Вони дозволяють нам виконувати багато видів маніпуляцій з даними та поділяються на такі часто використовувані групи.

  • Рядкові функції – оперувати рядковими типами даних
  • Числові функції – працювати з числовими типами даних
  • Функції дати – оперувати типами даних дати
  • Сукупні функції – працювати з усіма вищезазначеними типами даних і створювати підсумкові набори результатів.
  • Інші функції - MySQL також підтримує інші типи вбудованих функцій, але ми обмежуємо цей урок групами, названими вище.

Давайте тепер детально розглянемо кожну з вищезгаданих груп. Ми пояснимо найчастіше використовувані функції, використовуючи нашу зразкову базу даних «Myflixdb».

Рядкові функції

Рядкові функції працюють з текстовими значеннями. У нашій таблиці фільмів назви зберігаються з використанням комбінації малих та великих літер. Припустимо, нам потрібен запит, який повертає назви у верхньому регістрі. Функція «UCASE» приймає рядок як параметр і перетворює кожну літеру у верхню, як показано в сценарії нижче.

SELECT `movie_id`, `title`, UCASE(`title`) AS `upper_case_title` FROM `movies`;

ТУТ

  • UCASE(`назва`) — це вбудована функція, яка приймає заголовок як параметр і повертає його великими літерами.
  • AS `заголовок_у_великому_регістрі` надає обчисленому стовпцю псевдонім, тому результуючий набір містить читабельний заголовок замість необробленого виразу.

Виконання наведеного вище сценарію в MySQL Порівняння Workbench з Myflixdb дає нам результати, показані нижче.

movie_id назву заголовок_у_великих_літер
16 67% винний 67% ВИННИЙ
6 Ангели та демони АНГЕЛИ ТА ДЕМОНИ
4 Code Ім'я Блек КОДОВЕ ІМ'Я БЛЕК
5 Татові маленькі дівчатка ТАТОВІ МАЛЕНЬКІ ДІВЧАТКИ
7 Давінці Code КОД ДА ВІНЧІ
2 Забути Сару Маршал ЗАБУВАЮЧИ САРУ МАРШАЛ
9 Honey moonERS HONEY MOONERS
19 фільм 3 року ФІЛЬМ 3
1 Пірати Карибського моря 4 ПІРАТИ КАРИБСЬКОГО МОРЯ 4
18 зразок фільму ЗРАЗОК ФІЛЬМУ
17 Великий диктатор ВЕЛИКИЙ ДИКТАТОР
3 X-Men Люди Ікс

Варто пам'ятати двох супутників разом з UCASE: ЛКАСЕ перетворює рядок у нижній регістр та КОНКАТ об'єднує два або більше рядків в один. Повний список див. MySQL посилання на рядкову функцію.

Числові функції

Як згадувалося раніше, числові функції працюють з числовими типами даних. Ми також можемо виконувати математичні обчислення над числовими даними безпосередньо в наших SQL-інструкціях.

Арифметичні оператори

MySQL підтримує такі арифметичні оператори, які можна використовувати для виконання обчислень в SQL-інструкціях.

ІМ'Я Опис
DIV Ціле ділення
/ Роздільна
- нижчеtracції
+ Доповнення
* Множення
% або MOD Модуль

Приклади кожного оператора наведено нижче.

Цілочисельне ділення (DIV) — DIV відкидає дробову частину та повертає лише ціле число.

SELECT 23 DIV 6;

Виконання вищезазначеного сценарію дає нам 3.

Оператор ділення (/) — на відміну від DIV, оператор ділення зберігає десяткову частину результату.

SELECT 23 / 6;

Виконання вищезазначеного сценарію дає нам 3.8333.

нижчеtracоператор ції (-)

SELECT 23 - 6;

Виконання вищезазначеного сценарію дає нам 17.

Оператор додавання (+)

SELECT 23 + 6;

Виконання вищезазначеного сценарію дає нам 29.

Оператор множення (*)

SELECT 23 * 6 AS `multiplication_result`;

Результат:

результат_множення
138

Оператор модуля (% або MOD)

Оператор модуля ділить N на M і дає нам остачу. Розглянемо приклад з оператором модуля, використовуючи ті ж значення, що й у попередніх прикладах.

SELECT 23 % 6;
-- OR, equivalently:
SELECT 23 MOD 6;

Виконання будь-якого з цих сценаріїв дає нам 5.

Давайте тепер розглянемо деякі з поширених числових функцій у MySQL.

ПОЛЯ – ця функція видаляє десяткові знаки з числа та округляє його до найближчого цілого числа. Скрипт, наведений нижче, демонструє її використання.

SELECT FLOOR(23 / 6) AS `floor_result`;

Результат:

результат_поверху
3

КРУГЛИЙ – ця функція округляє число до найближчого цілого числа. Оскільки 23 / 6 дорівнює 3.8333, ROUND повертає 4, а FLOOR повертає 3 — ці дві функції не є взаємозамінними.

SELECT ROUND(23 / 6) AS `round_result`;

Результат:

результат_раунду
4

РАНД – ця функція генерує випадкове число. Його значення змінюється щоразу, коли викликається функція. Наведений нижче скрипт демонструє її використання.

SELECT RAND() AS `random_result`;

Функції дати

Функції дати працюють з типами даних дата та дата-час. DATE_FORMAT – це функція, яка вирішує проблему «РРРР-ММ-ДД проти ДД-ММ-РРРР», описану у вступі.

ФОРМАТ_ДАТИ приймає два параметри: значення дати для форматування та рядок форматування, побудований з заповнювачів. Наведений нижче скрипт повертає кожну дату випуску у форматі день-місяць-рік, який запитували наші користувачі.

SELECT `title`, DATE_FORMAT(`date_released`, '%d-%m-%Y') AS `formatted_date`
FROM `movies`;

Найчастіше використовувані заповнювачі формату наведено нижче.

Заповнювач Сенс Приклад виводу
%d День місяця, дві цифри 04
%m Місяць, дві цифри 08
%Y Рік, чотири цифри 2012
%M Повна назва місяця серпня
%H:%i:%s Hours, хвилини, секунди 14:35:09

Три інші функції дати постійно з'являються в повсякденній роботі:

  • ЗВОРОЩЕННЯ() повертає поточну дату у форматі РРРР-ММ-ДД.
  • NOW () повертає поточну дату та часу.
  • ДАТА_ПОДІБНО(d1, d2) повертає кількість днів між двома датами — основу будь-якого звіту про прострочену орендну плату.

Повний список див. MySQL довідка про функції дати та часу.

Збережені функції

Вбудовані функції охоплюють поширені випадки. Коли бізнес-правило є більш конкретним, ми пишемо своє власне — і саме для цього і існує збережена функція.

Збережені функції поводяться так само, як вбудовані функції, за винятком того, що ви визначаєте їх самостійно. Після створення збережену функцію можна використовувати в SQL-інструкціях точно так само, як і будь-яку іншу функцію. Основний синтаксис показано нижче.

CREATE FUNCTION sf_name ([parameter(s)])
RETURNS data_type
[DETERMINISTIC | NOT DETERMINISTIC]
BEGIN
    -- procedural statements
END

ТУТ

  • «СТВОРИТИ ФУНКЦІЮ sf_name ([параметр(и)])» є обов'язковим і повідомляє MySQL сервер для створення функції з назвою `sf_name` з необов'язковими параметрами, визначеними в дужках.
  • «ПОВЕРТАЄ тип_даних» є обов'язковим і вказує тип даних, який повертає функція.
  • «ДЕТЕРМІНІСТИЧНИЙ» оголошує, що функція повертає те саме значення щоразу, коли надаються ті самі аргументи. «НЕ ДЕТЕРМІНІСТИЧНИЙ» заявляє про протилежне.
  • «ПОЧАТОК … КІНЕЦЬ» обгортає процедурний код, який виконує функція.

Припустимо, нам потрібно знати, які орендовані фільми вже повернуті. Ми можемо створити збережену функцію, яка приймає дату повернення як параметр і порівнює її з поточною датою на сервері. Якщо поточна дата більша за дату повернення, фільм вважається простроченим, і ми повертаємо «Так»; інакше ми повертаємо «Ні».

DELIMITER |
CREATE FUNCTION sf_past_movie_return_date (return_date DATE)
RETURNS VARCHAR(3)
NOT DETERMINISTIC
BEGIN
    DECLARE sf_value VARCHAR(3);
    IF CURDATE() > return_date THEN
        SET sf_value = 'Yes';
    ELSEIF CURDATE() <= return_date THEN
        SET sf_value = 'No';
    END IF;
    RETURN sf_value;
END|
DELIMITER ;

⚠️ Увага — не позначайте цю функцію як ДЕТЕРМІНІСТИЧНУ. Тіло функції викликає CURDATE(), тому той самий аргумент може повернути «Ні» сьогодні та «Так» завтра. Оголошення функції DETERMINISTIC, що залежить від часу, вводить оптимізатор в оману та є небезпечним для реплікації на основі операторів. Використовуйте НЕ ДЕТЕРМІНІСТОВИЙ щоразу, коли тіло викликає CURDATE(), NOW() або RAND().

Виконання наведеного вище скрипта створює збережену функцію `sf_past_movie_return_date`. Тепер перевіримо її.

SELECT `movie_id`, `membership_number`, `return_date`, CURDATE(),
       sf_past_movie_return_date(`return_date`) AS `is_overdue`
FROM `movierentals`;

Виконання наведеного вище сценарію в MySQL Аналіз Workbench для myflixdb дає нам такі результати.

movie_id member_number дата_повернення ЗВОРОЩЕННЯ() прострочено
1 1 NULL 04-08-2012 NULL
2 1 25-06-2012 04-08-2012 Так
2 3 25-06-2012 04-08-2012 Так
2 2 25-06-2012 04-08-2012 Так
3 3 NULL 04-08-2012 NULL

Зверніть увагу на два рядки NULL. Коли `return_date` має значення NULL, обидва порівняння оцінюються як NULL, а не TRUE або FALSE, тому жодна з гілок IF не виконується, і функція повертає NULL — очікуваний результат, оскільки неповернений фільм не має дати повернення для порівняння.

Визначені користувачем функції

Коли самого лише SQL недостатньо швидкого, MySQL дозволяє третій варіант. Користувацькі функції (UDF) пишуться компільованою мовою, такою як C or C++, вбудовані в спільну бібліотеку та зареєстровані на сервері. Після додавання вони викликаються так само, як і будь-які інші функції. Оскільки UDF виконується як власний код всередині серверного процесу, вона підходить для важких обчислень, але помилка в одній з них може призвести до збою сервера, тому UDF використовуються набагато рідше, ніж збережені функції.

Вбудовані, збережені та користувацькі функції: які з них слід використовувати?

Усі три родини повертають одне значення та можуть бути викликані з будь-якого SQL-запиту, але вони відрізняються тим, хто їх пише, де вони виконуються та який рівень ризику вони несуть. У таблиці нижче підсумовано ці відмінності.

критерій Вбудовані функції Збережені функції Користувацькі функції (UDF)
Хто це пише Відправлено з MySQL Ви, в SQL Ви, на C або C++
Де воно живе Всередині сервера Всередині бази даних, створеної за допомогою CREATE FUNCTION Скомпільована спільна бібліотека, завантажена сервером
Типове використання Форматування, математика, агрегація Багаторазові бізнес-правила, такі як прострочений чек SQL не може виразити складну для процесора або спеціалізовану логіку
Основний ризик ніхто Повільно, якщо викликається рядок за рядком над великою таблицею Збій у бібліотеці може призвести до виходу з ладу сервера

Як правило, починайте з вбудованої функції. Якщо жодна не підходить, напишіть збережену функцію, щоб правило зберігалося в одному місці. Звертайтеся до UDF лише тоді, коли збережена функція є помітно занадто повільною.

Поширені запитання

Функція повинна повертати рівно одне значення та може використовуватися всередині виразів SELECT, WHERE або ORDER BY. Збережена процедура повертає нуль або багато наборів результатів, не може бути вбудована у вираз та викликається за допомогою оператора CALL.

Виконайте DROP FUNCTION IF EXISTS sf_name; потім створіть її знову. MySQL не має функції CREATE або REPLACE, а функція ALTER змінює лише такі характеристики, як коментар або тип безпеки, але ніколи не змінює тіло коду.

Вони можуть. Функція, обгорнута навколо індексованого стовпця в реченні WHERE, запобігає MySQL від використання цього індексу, що призводить до повного сканування. Фільтруйте за необробленим стовпцем і застосовуйте функцію лише до списку SELECT.

Так. Помічники ШІ можуть створювати код CREATE FUNCTION на основі правила, написаного простою англійською мовою. Завжди перевіряйте згенерований текст на наявність правильної характеристики DETERMINISTIC, обробки NULL та типів даних параметрів, перш ніж запускати його на робочому сервері.

Ні. Моделі ШІ можуть вигадувати назви функцій, пропускати випадки NULL або ігнорувати відмінності у версіях. Тестуйте кожну згенеровану функцію на копії даних та перевіряйте результати за запитом, який ви написали та перевірили самостійно.

Підсумуйте цей пост за допомогою: