У цій лекції ми розберемо, які типи даних підтримуються в PL/pgSQL, і навчимось ефективно з ними працювати. Основна увага буде на чотирьох типах даних:
INTEGERдля роботи з числами.TEXTдля обробки рядків.BOOLEANдля роботи з логічними значеннями.RECORDдля роботи з динамічними структурами даних.
Кожен тип даних ми розглянемо на прикладах, щоб ти міг бачити їх використання на практиці.
Підтримувані типи даних у PL/pgSQL
PL/pgSQL підтримує всі типи даних, які знайомі тобі з PostgreSQL. Від простих числових (INTEGER, NUMERIC) до більш складних, таких як масиви і JSONB. Давай пробіжимось по основних.
Примітивні типи:
INTEGER,BIGINT,FLOAT,NUMERIC— числові типи.TEXT,CHAR,VARCHAR— текстові.BOOLEAN— логічний тип даних.
Складні типи:
RECORD— для роботи з динамічними наборами даних.ROWTYPE— для роботи з типами рядків таблиці.- Масиви і JSON — будемо розбирати пізніше в курсі.
Робота з типом INTEGER
INTEGER — це один із найпопулярніших типів даних. Він використовується для зберігання цілих чисел. У PL/pgSQL цим типом ти можеш користуватись для розрахунків, роботи з ідентифікаторами записів і перевірки умов.
Приклад: підрахунок кількості записів
Припустимо, у нас є таблиця students, і ми хочемо дізнатись, скільки студентів записано в базі.
DO $$
DECLARE
total_students INTEGER; -- Змінна для зберігання кількості студентів
BEGIN
SELECT COUNT(*) INTO total_students FROM students; -- Зберігаємо результат запиту в змінну
RAISE NOTICE 'Кількість студентів: %', total_students; -- Виводимо повідомлення
END;
$$;
Важливі моменти при роботі з INTEGER:
- У PL/pgSQL присвоєння змінній значення робиться через ключове слово
INTO. - Якщо ти спробуєш зберегти в
INTEGERдробове значення — отримаєш помилку. Для таких випадків юзай типNUMERICабоFLOAT.
Робота з типом TEXT
TEXT використовується для зберігання рядкових даних. Він стане в нагоді, коли треба працювати з іменами, описами чи будь-якими іншими текстами.
Приклад: вивід імен студентів
У цьому прикладі ми виведемо імена всіх студентів із таблиці students.
DO $$
DECLARE
student_name TEXT; -- Змінна для імені студента
BEGIN
FOR student_name IN SELECT name FROM students LOOP
RAISE NOTICE 'Ім'я студента: %', student_name; -- Виводимо кожне ім'я
END LOOP;
END;
$$;
Корисні функції для роботи з TEXT:
UPPER()іLOWER()— переведення у верхній/нижній регістр.CONCAT()— з'єднання рядків.LENGTH()— довжина рядка.
Наприклад:
DO $$
DECLARE
full_name TEXT;
BEGIN
full_name := CONCAT('Алекс', ' Мін'); -- З'єднуємо рядки
RAISE NOTICE 'Повне ім'я: %', UPPER(full_name); -- Друкуємо ім'я у верхньому регістрі
END;
$$;
Робота з типом BOOLEAN
BOOLEAN відповідає за зберігання логічних значень: TRUE, FALSE і NULL. Цей тип особливо зручний при перевірці умов і фільтрації даних.
Приклад: перевірка активності студента
Припустимо, у тебе є таблиця students з колонкою is_active, яка показує, чи активний студент.
DO $$
DECLARE
is_active BOOLEAN; -- Змінна для зберігання значення активності
BEGIN
SELECT is_active INTO is_active FROM students WHERE id = 1; -- Отримуємо значення з таблиці
IF is_active THEN
RAISE NOTICE 'Студент активний!';
ELSE
RAISE NOTICE 'Студент НЕ активний.';
END IF;
END;
$$;
Важливі моменти при роботі з BOOLEAN:
- Логічні значення можна юзати напряму в умовах
IFіWHILE. - Значення
NULLу логіці вважається "невизначеним", тому враховуй це при перевірках.
Робота з типом RECORD
RECORD — це потужний тип даних, який використовується для зберігання рядків даних без наперед заданої структури. Він особливо зручний, коли ти працюєш з результатами SQL-запитів, які повертають кілька колонок.
Приклад: обхід усіх записів таблиці
У наступному прикладі ми обходимо всі записи таблиці students і виводимо ім'я та ID кожного студента.
DO $$
DECLARE
student RECORD; -- Динамічний тип для зберігання рядка даних
BEGIN
FOR student IN SELECT id, name FROM students LOOP
RAISE NOTICE 'ID: %, Ім'я: %', student.id, student.name; -- Звертаємось до колонок запису
END LOOP;
END;
$$;
Важливі моменти при роботі з RECORD:
- Змінні типу
RECORDзаповнюються тільки всередині циклу або при використанні запитуSELECT INTO. - Викликати колонки можна через
record.column_name.
Типи даних ROWTYPE для роботи з таблицями
Якщо ти хочеш зберегти запис із таблиці цілком (і при цьому хочеш чітку типізацію), можна юзати тип ROWTYPE. Він автоматично наслідує структуру рядка таблиці.
Приклад: робота з типом ROWTYPE
DO $$
DECLARE
student students%ROWTYPE; -- Змінна зі структурою рядка таблиці students
BEGIN
SELECT * INTO student FROM students WHERE id = 1; -- Завантажуємо дані рядка в змінну
RAISE NOTICE 'Ім'я студента: %, Курс: %', student.name, student.course;
END;
$$;
Відмінності між RECORD і ROWTYPE
| Характеристика | RECORD | ROWTYPE |
|---|---|---|
| Структура колонок | Не визначена наперед | Залежить від таблиці або запиту |
| Використання | Гнучкість для будь-якого результату | Жорстка прив'язка до структури |
Практичний приклад
Давай напишемо функцію, яка повертає кількість активних студентів і їх імена.
CREATE FUNCTION active_students_report() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT id, name FROM students WHERE is_active = TRUE;
END;
$$ LANGUAGE plpgsql;
Виклик функції:
SELECT * FROM active_students_report();
Помилки при роботі з типами даних
Іноді робота з даними призводить до помилок. Ось кілька поширених моментів:
- Помилка типу: спроба записати рядок у змінну
INTEGER(наприклад,my_var := 'abc';). - Використання
NULLтам, де очікуєтьсяTRUEабоFALSE. - Неправильне використання
RECORDбез ініціалізації.
Як уникати помилок:
- Завжди явно задавай тип змінних.
- Перевіряй типи даних колонок у таблицях перед записом.
- Юзай команди для дебагу, такі як
RAISE NOTICE.
Тепер ти знаєш, як працювати з типами даних INTEGER, TEXT, BOOLEAN і RECORD у PL/pgSQL. Це знання дозволить тобі створювати більш складні й потужні програми на процедурній мові PostgreSQL.
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ