Загрузка данных


Написать код функции в PostgreSQL без долларового цитирования (`$$`) можно, используя обычные одинарные кавычки. В этом случае все кавычки внутри кода функции нужно **удваивать** (`''`), чтобы база понимала, что это текст внутри текста.

Вот полный проект с нуля в этом стиле.

### Шаг 1: Создание таблиц
Выполните в Query Tool:

```sql
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username TEXT NOT NULL,
    email TEXT
);

CREATE TABLE users_log (
    log_id SERIAL PRIMARY KEY,
    user_id INT,
    operation TEXT,
    changed_by TEXT,
    changed_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    data_json JSONB
);
```

### Шаг 2: Создание функции и триггера (без знака $)
Здесь вместо `$$` используются обычные кавычки `'`, а внутри кода все текстовые значения пишутся с двойными кавычками `''`.

```sql
CREATE OR REPLACE FUNCTION log_changes()
RETURNS TRIGGER AS
'
BEGIN
    IF (TG_OP = ''DELETE'') THEN
        INSERT INTO users_log (user_id, operation, changed_by, data_json)
        VALUES (OLD.id, TG_OP, current_user, to_jsonb(OLD));
    ELSE
        INSERT INTO users_log (user_id, operation, changed_by, data_json)
        VALUES (NEW.id, TG_OP, current_user, to_jsonb(NEW));
    END IF;

    PERFORM pg_notify(''audit_chan'', ''Изменение: '' || TG_OP);

    IF (TG_OP = ''DELETE'') THEN RETURN OLD; ELSE RETURN NEW; END IF;
END;
'
LANGUAGE plpgsql;

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

### Шаг 3: Настройка уведомлений
Выполните, чтобы начать слушать сигналы:

```sql
LISTEN audit_chan;
```

### Шаг 4: Проверка для экзамена

**1. Добавление записи:**
```sql
INSERT INTO users (username, email) VALUES ('student', 'test@test.ru');
```

**2. Просмотр уведомления:**
Нажмите на вкладку **Messages** внизу. Вы увидите строку с текстом `Изменение: INSERT`.

**3. Отчет за месяц:**
```sql
SELECT * FROM users_log 
WHERE changed_at >= NOW() - INTERVAL '1 month' 
ORDER BY changed_at DESC;
```

---

### Ответы на теорию (кратко):

1.  **Аудит:** Это фиксация истории изменений. Настроен через триггер и таблицу `users_log`.
2.  **Уведомления:** Использован механизм `NOTIFY`. Он передает сигнал о событии внешним программам (аналог Database Mail).
3.  **Защита:** Реализуется через роли доступа (GRANT/REVOKE) и политики безопасности строк (RLS).
4.  **Почему без $$?** Использовано стандартное строковое цитирование. Все внутренние кавычки в коде пришлось экранировать (писать по две), чтобы база не приняла их за конец функции.