Как в SQL реализовать обновление временной метки последней активности пользователя (last_activity) через подготовленные выражения (prepare)?

Обновление временной метки последней активности пользователя через подготовленные выражения — стандартная задача в веб-разработке. Подготовленные выражения (prepared statements) защищают от SQL-инъекций и повышают производительность при многократном выполнении одного запроса.

## Базовый принцип

Подготовленное выражение разделяет SQL-запрос и передаваемые данные. Сначала запрос компилируется сервером, затем в него подставляются параметры через привязку.

## Пример на PHP с PDO (MySQL/PostgreSQL)

php
$pdo = new PDO(‘mysql:host=localhost;dbname=mydb’, ‘user’, ‘password’);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

$sql = «UPDATE users SET last_activity = NOW() WHERE id = :user_id»;
$stmt = $pdo->prepare($sql);
$stmt->bindParam(‘:user_id’, $userId, PDO::PARAM_INT);
$stmt->execute();

Здесь `NOW()` — функция базы данных, возвращающая текущее время. Она не является пользовательским вводом, поэтому её безопасно вставлять прямо в запрос.

## Пример с передачей метки времени из PHP

Если нужно передать конкретное значение времени:

php
$lastActivity = date(‘Y-m-d H:i:s’);
$sql = «UPDATE users SET last_activity = :last_activity WHERE id = :user_id»;
$stmt = $pdo->prepare($sql);
$stmt->bindParam(‘:last_activity’, $lastActivity, PDO::PARAM_STR);
$stmt->bindParam(‘:user_id’, $userId, PDO::PARAM_INT);
$stmt->execute();

## Пример с MySQLi

php
$mysqli = new mysqli(‘localhost’, ‘user’, ‘password’, ‘mydb’);
$stmt = $mysqli->prepare(«UPDATE users SET last_activity = NOW() WHERE id = ?»);
$stmt->bind_param(‘i’, $userId);
$stmt->execute();
$stmt->close();

## PostgreSQL через pg_prepare

php
$conn = pg_connect(«host=localhost dbname=mydb user=user password=pass»);
pg_prepare($conn, ‘update_activity’, ‘UPDATE users SET last_activity = NOW() WHERE id = $1’);
pg_execute($conn, ‘update_activity’, [$userId]);

## Структура таблицы

Для корректной работы поле `last_activity` должно иметь тип `DATETIME` или `TIMESTAMP`:

sql
ALTER TABLE users ADD COLUMN last_activity TIMESTAMP DEFAULT NULL;

## Массовое обновление нескольких пользователей

Подготовленное выражение эффективно при многократном вызове в цикле:

php
$stmt = $pdo->prepare(«UPDATE users SET last_activity = NOW() WHERE id = :id»);
foreach ($userIds as $id) {
$stmt->execute([‘:id’ => $id]);
}

## Рекомендации

— Используйте `NOW()` или `CURRENT_TIMESTAMP` на стороне БД для точности времени сервера.
— Всегда проверяйте количество затронутых строк через `$stmt->rowCount()`, чтобы убедиться в успешном обновлении.
— При высокой нагрузке рассмотрите обновление `last_activity` не при каждом запросе, а с интервалом (например, раз в минуту), чтобы снизить нагрузку на БД.
— Добавьте индекс на поле `last_activity`, если планируете выборки по нему (например, поиск неактивных пользователей).


Задайте вопрос нейросети

Не нашли ответ? Спросите ИИ — он подготовит развёрнутую статью.