-- Универсальный код для MySQL и PostgreSQL
-- Определяем тип СУБД и выполняем соответствующие команды
-- 1. Определение типа СУБД
DO $$
BEGIN
-- Для PostgreSQL
IF EXISTS (SELECT 1 FROM pg_settings WHERE name = 'server_version') THEN
-- Удаление объектов если существуют (PostgreSQL)
DROP TABLE IF EXISTS clients_age;
DROP FUNCTION IF EXISTS calculate_age_category(date);
DROP FUNCTION IF EXISTS set_age_category();
DROP TRIGGER IF EXISTS tr_set_age_category ON clients_age;
DROP TABLE IF EXISTS clients;
DROP TABLE IF EXISTS clients_archive;
DROP FUNCTION IF EXISTS archive_client();
DROP TRIGGER IF EXISTS archive_client_on_delete ON clients;
-- Создание таблицы клиентов с возрастными категориями (PostgreSQL)
CREATE TABLE clients_age (
client_id SERIAL PRIMARY KEY,
client_name TEXT NOT NULL,
birth_date DATE NOT NULL,
age_category TEXT NOT NULL,
registration_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Функция для определения возрастной категории (PostgreSQL)
CREATE OR REPLACE FUNCTION calculate_age_category(birth_date DATE)
RETURNS TEXT AS $$
DECLARE
age_years INT;
BEGIN
age_years := DATE_PART('year', AGE(birth_date));
RETURN CASE
WHEN age_years < 1 THEN
CASE WHEN (CURRENT_DATE - birth_date) <= 10 THEN 'Н' ELSE 'Г' END
WHEN age_years <= 2 THEN 'Д-0'
WHEN age_years <= 7 THEN 'Д-1'
WHEN age_years <= 12 THEN 'Д-2'
WHEN age_years <= 16 THEN 'Пд'
WHEN age_years <= 21 THEN 'Ю'
WHEN age_years <= 60 THEN 'Ср'
WHEN age_years <= 75 THEN 'Пж'
WHEN age_years <= 90 THEN 'Ст'
ELSE 'Д'
END;
END;
$$ LANGUAGE plpgsql;
-- Триггерная функция для автоматического расчета категории
CREATE OR REPLACE FUNCTION set_age_category()
RETURNS TRIGGER AS $$
BEGIN
NEW.age_category := calculate_age_category(NEW.birth_date);
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Создание триггера
CREATE TRIGGER tr_set_age_category
BEFORE INSERT OR UPDATE OF birth_date ON clients_age
FOR EACH ROW
EXECUTE FUNCTION set_age_category();
-- Вставка тестовых данных
INSERT INTO clients_age (client_name, birth_date) VALUES
('Иванов Иван', '2005-09-27'),
('Петрова Мария', '2010-03-15'),
('Сидоров Алексей', '1980-07-20'),
('Козлова Анна', '2023-01-10'),
('Смирнов Дмитрий', '1950-05-30');
-- Создание таблиц для архивации (PostgreSQL)
CREATE TABLE clients (
client_id SERIAL PRIMARY KEY,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100) UNIQUE,
phone VARCHAR(20),
registration_date DATE
);
CREATE TABLE clients_archive (
archive_id SERIAL PRIMARY KEY,
original_client_id INT,
first_name VARCHAR(50) NOT NULL,
last_name VARCHAR(50) NOT NULL,
email VARCHAR(100),
phone VARCHAR(20),
registration_date DATE,
transfer_date TIMESTAMP
);
-- Функция и триггер для архивации
CREATE OR REPLACE FUNCTION archive_client()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO clients_archive (
original_client_id, first_name, last_name,
email, phone, registration_date, transfer_date
) VALUES (
OLD.client_id, OLD.first_name, OLD.last_name,
OLD.email, OLD.phone, OLD.registration_date, NOW()
);
RETURN OLD;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER archive_client_on_delete
BEFORE DELETE ON clients
FOR EACH ROW
EXECUTE FUNCTION archive_client();
-- Вставка тестовых данных для архивации
INSERT INTO clients (first_name, last_name, email, phone, registration_date) VALUES
('Иван', 'Иванов', 'ivan@example.com', '79161234567', '2023-01-15'),
('Мария', 'Петрова', 'petr@example.com', '79159876543', '2023-02-20'),
('Алексей', 'Сидоров', 'maria@example.com', '79035432109', '2023-03-10');
-- Тестирование
DELETE FROM clients WHERE client_id = 1;
-- Вывод результатов
RAISE NOTICE '=== Результаты для PostgreSQL ===';
ELSE
-- Для MySQL
SET @sql = CONCAT(
'DROP TABLE IF EXISTS clients;',
'DROP TABLE IF EXISTS clients_archive;',
'DROP TRIGGER IF EXISTS archive_client_on_delete;',
-- Создание таблиц для архивации (MySQL)
'CREATE TABLE IF NOT EXISTS clients (',
' client_id INT AUTO_INCREMENT PRIMARY KEY,',
' first_name VARCHAR(50) NOT NULL,',
' last_name VARCHAR(50) NOT NULL,',
' email VARCHAR(100) UNIQUE,',
' phone VARCHAR(20),',
' registration_date DATE',
') ENGINE=InnoDB;',
'CREATE TABLE IF NOT EXISTS clients_archive (',
' archive_id INT AUTO_INCREMENT PRIMARY KEY,',
' original_client_id INT,',
' first_name VARCHAR(50) NOT NULL,',
' last_name VARCHAR(50) NOT NULL,',
' email VARCHAR(100),',
' phone VARCHAR(20),',
' registration_date DATE,',
' transfer_date DATETIME',
') ENGINE=InnoDB;',
-- Триггер для архивации (MySQL)
'CREATE TRIGGER archive_client_on_delete ',
'BEFORE DELETE ON clients ',
'FOR EACH ROW ',
'BEGIN ',
' INSERT INTO clients_archive (',
' original_client_id, first_name, last_name,',
' email, phone, registration_date, transfer_date',
' ) VALUES (',
' OLD.client_id, OLD.first_name, OLD.last_name,',
' OLD.email, OLD.phone, OLD.registration_date, NOW()',
' ); ',
'END;',
-- Вставка тестовых данных
'INSERT INTO clients (first_name, last_name, email, phone, registration_date) VALUES ',
'("Иван", "Иванов", "ivan@example.com", "79161234567", "2023-01-15"),',
'("Мария", "Петрова", "petr@example.com", "79159876543", "2023-02-20"),',
'("Алексей", "Сидоров", "maria@example.com", "79035432109", "2023-03-10");',
-- Тестирование
'DELETE FROM clients WHERE client_id = 1;'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- Вывод результатов
SELECT '=== Результаты для MySQL ===' AS message;
SELECT 'Текущие клиенты:' AS title;
SELECT * FROM clients;
SELECT 'Архивные записи:' AS title;
SELECT * FROM clients_archive;
END IF;
END $$;
-- Вывод результатов для PostgreSQL
SELECT '=== Возрастные категории ===' AS title;
SELECT
client_name,
birth_date,
age_category,
EXTRACT(YEAR FROM AGE(birth_date)) AS age_years,
CURRENT_DATE - birth_date AS age_days
FROM clients_age;
SELECT '=== Архив клиентов ===' AS title;
SELECT 'Текущие клиенты:' AS subtitle;
SELECT * FROM clients;
SELECT 'Архивные записи:' AS subtitle;
SELECT * FROM clients_archive;