← Назад к вопросам

Можно ли написать на SQL программу?

1.0 Junior🔥 201 комментариев
#Базы данных (SQL)

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Можно ли написать на SQL программу?

Прямой ответ: ДА, МОЖНО, НО РЕДКО НУЖНО

Technically, SQL это язык программирования (Turing-complete в некоторых реализациях), но на нём редко пишут полноценные программы. Однако некоторые СУБД позволяют писать довольно сложную логику прямо в SQL или через расширения.

SQL как язык программирования

SQL - это не просто язык запросов, это полноценный язык с:

  • Переменными
  • Циклами
  • Условиями
  • Функциями
  • Структурированной обработкой данных
-- PostgreSQL: PL/pgSQL - встроенный язык программирования

CREATE FUNCTION calculate_salary(employee_id INT) 
RETURNS NUMERIC AS $$
DECLARE
    base_salary NUMERIC;
    bonus NUMERIC;
    total NUMERIC;
BEGIN
    -- Выборка данных
    SELECT salary INTO base_salary
    FROM employees
    WHERE id = employee_id;
    
    -- Условная логика
    IF base_salary > 50000 THEN
        bonus := base_salary * 0.15;
    ELSIF base_salary > 30000 THEN
        bonus := base_salary * 0.10;
    ELSE
        bonus := base_salary * 0.05;
    END IF;
    
    -- Вычисление
    total := base_salary + bonus;
    
    -- Возврат результата
    RETURN total;
END;
$$ LANGUAGE plpgsql;

-- Использование
SELECT calculate_salary(1) AS employee_salary;

Способ 1: Хранимые процедуры (Stored Procedures)

-- MySQL: простая хранимая процедура

DELIMITER $$
CREATE PROCEDURE transfer_money(
    FROM_ACCOUNT INT,
    TO_ACCOUNT INT,
    AMOUNT DECIMAL(10, 2)
)
BEGIN
    DECLARE balance DECIMAL(10, 2);
    
    START TRANSACTION;
    
    -- Проверка баланса
    SELECT current_balance INTO balance
    FROM accounts
    WHERE id = FROM_ACCOUNT
    FOR UPDATE;
    
    IF balance >= AMOUNT THEN
        -- Снять с первого счёта
        UPDATE accounts
        SET current_balance = current_balance - AMOUNT
        WHERE id = FROM_ACCOUNT;
        
        -- Добавить на второй счёт
        UPDATE accounts
        SET current_balance = current_balance + AMOUNT
        WHERE id = TO_ACCOUNT;
        
        COMMIT;
        SELECT 'Transfer successful' AS result;
    ELSE
        ROLLBACK;
        SELECT 'Insufficient funds' AS error;
    END IF;
END$$
DELIMITER ;

-- Вызов
CALL transfer_money(1, 2, 100.50);

Способ 2: Триггеры (Triggers)

-- PostgreSQL: триггер для логирования

CREATE TABLE audit_log (
    id SERIAL PRIMARY KEY,
    table_name TEXT,
    operation TEXT,
    old_data JSONB,
    new_data JSONB,
    timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

CREATE FUNCTION log_changes() 
RETURNS TRIGGER AS $$
BEGIN
    IF TG_OP = 'DELETE' THEN
        INSERT INTO audit_log (table_name, operation, old_data)
        VALUES (TG_TABLE_NAME, TG_OP, row_to_json(OLD));
    ELSIF TG_OP = 'UPDATE' THEN
        INSERT INTO audit_log (table_name, operation, old_data, new_data)
        VALUES (TG_TABLE_NAME, TG_OP, row_to_json(OLD), row_to_json(NEW));
    ELSIF TG_OP = 'INSERT' THEN
        INSERT INTO audit_log (table_name, operation, new_data)
        VALUES (TG_TABLE_NAME, TG_OP, row_to_json(NEW));
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER users_audit
AFTER INSERT OR UPDATE OR DELETE ON users
FOR EACH ROW
EXECUTE FUNCTION log_changes();

Способ 3: Рекурсивные запросы (CTE)

-- Вычисление факториала на SQL
WITH RECURSIVE factorial AS (
    -- Base case
    SELECT 1 AS n, 1 AS result
    
    UNION ALL
    
    -- Recursive case
    SELECT n + 1, result * (n + 1)
    FROM factorial
    WHERE n < 5  -- Условие выхода из рекурсии
)
SELECT * FROM factorial;

-- Результат:
-- n | result
-- 1 |      1
-- 2 |      2
-- 3 |      6
-- 4 |     24
-- 5 |    120

Способ 4: Сложные вычисления с циклами

-- PostgreSQL: вычисление рядов

CREATE FUNCTION fibonacci(n INT)
RETURNS INT AS $$
DECLARE
    a INT := 0;
    b INT := 1;
    i INT;
    temp INT;
BEGIN
    FOR i IN 1..n LOOP
        temp := a + b;
        a := b;
        b := temp;
    END LOOP;
    RETURN a;
END;
$$ LANGUAGE plpgsql;

SELECT fibonacci(10);  -- Результат: 55

Способ 5: Обработка текста и строк

-- PostgreSQL: работа со строками

CREATE FUNCTION reverse_string(input_str TEXT)
RETURNS TEXT AS $$
DECLARE
    result TEXT := '';
    i INT;
BEGIN
    FOR i IN REVERSE LENGTH(input_str)..1 LOOP
        result := result || SUBSTR(input_str, i, 1);
    END LOOP;
    RETURN result;
END;
$$ LANGUAGE plpgsql;

SELECT reverse_string('Hello');  -- Результат: olleH

Почему редко пишут полные программы на SQL?

  1. Плохая читаемость - SQL не очень удобен для сложной логики
  2. Отсутствие стандартизации - каждая СУБД своя синтаксис
  3. Ограниченные возможности - нет легкого доступа к сетевым операциям, файловой системе
  4. Сложность отладки - трудно отлаживать логику в БД
  5. Производительность - иногда медленнее чем в приложении
# Вместо этого пишут на Python с использованием SQL:

import sqlite3

def transfer_money(from_account, to_account, amount):
    conn = sqlite3.connect(':memory:')
    cursor = conn.cursor()
    
    try:
        # Логика обработки ошибок в Python
        balance = cursor.execute(
            'SELECT balance FROM accounts WHERE id = ?',
            (from_account,)
        ).fetchone()[0]
        
        if balance >= amount:
            cursor.execute(
                'UPDATE accounts SET balance = balance - ? WHERE id = ?',
                (amount, from_account)
            )
            cursor.execute(
                'UPDATE accounts SET balance = balance + ? WHERE id = ?',
                (amount, to_account)
            )
            conn.commit()
            return True
    except Exception as e:
        conn.rollback()
        raise
    finally:
        conn.close()

Когда всё же используют SQL-программы?

  • Триггеры - для автоматических действий при изменении данных
  • Хранимые процедуры - для сложных операций с данными в БД
  • Представления (Views) - для часто используемых запросов
  • Check constraints - для валидации данных

Вывод

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

  • Запросов к данным - основное применение
  • Хранимых процедур - сложная логика в БД
  • Триггеров - автоматизация действий

Для полноценной разработки приложений SQL комбинируют с языками программирования (Python, Java, JavaScript и т.д.), где логика читаема и легче поддерживается.