PDO::ERRMODE_EXCEPTION] ); echo "=== ИСПРАВЛЕНИЕ COLLATION В NEXTCLOUD ===\n\n"; // Находим все колонки с неправильной collation $query = " SELECT TABLE_NAME, COLUMN_NAME, DATA_TYPE, CHARACTER_SET_NAME, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ? AND TABLE_NAME LIKE 'oc_%' AND COLLATION_NAME = 'utf8mb3_general_ci' ORDER BY TABLE_NAME, COLUMN_NAME "; $stmt = $pdo->prepare($query); $stmt->execute([$dbName]); $columns = $stmt->fetchAll(PDO::FETCH_ASSOC); if (empty($columns)) { echo "✅ Все колонки уже имеют правильную collation!\n"; exit(0); } echo "Найдено колонок с неправильной collation: " . count($columns) . "\n\n"; $fixed = 0; $errors = 0; foreach ($columns as $col) { $table = $col['TABLE_NAME']; $column = $col['COLUMN_NAME']; $dataType = $col['DATA_TYPE']; $charSet = $col['CHARACTER_SET_NAME']; // Определяем новый тип данных $newCharSet = 'utf8mb4'; $newCollation = 'utf8mb4_general_ci'; // Для TEXT типов нужно указать CHARACTER SET $alterQuery = "ALTER TABLE `$table` MODIFY COLUMN `$column` "; if (in_array(strtoupper($dataType), ['VARCHAR', 'CHAR', 'TEXT', 'TINYTEXT', 'MEDIUMTEXT', 'LONGTEXT'])) { // Получаем текущие параметры колонки $colInfoQuery = "SHOW FULL COLUMNS FROM `$table` WHERE Field = ?"; $colInfoStmt = $pdo->prepare($colInfoQuery); $colInfoStmt->execute([$column]); $colInfo = $colInfoStmt->fetch(PDO::FETCH_ASSOC); if ($colInfo) { $type = $colInfo['Type']; // Заменяем charset в типе $type = preg_replace('/utf8mb3/i', 'utf8mb4', $type); $type = preg_replace('/utf8(_general_ci)?/i', 'utf8mb4', $type); $null = $colInfo['Null'] === 'YES' ? 'NULL' : 'NOT NULL'; $default = $colInfo['Default'] !== null ? "DEFAULT '{$colInfo['Default']}'" : ''; $extra = $colInfo['Extra'] ?: ''; $alterQuery .= "$type CHARACTER SET $newCharSet COLLATE $newCollation $null $default $extra"; } else { echo "⚠️ Не удалось получить информацию о колонке $table.$column\n"; continue; } } else { // Для других типов просто меняем collation $alterQuery .= "`$column` $dataType CHARACTER SET $newCharSet COLLATE $newCollation"; } try { echo "Исправляю: $table.$column ... "; $pdo->exec($alterQuery); echo "✅\n"; $fixed++; } catch (PDOException $e) { echo "❌ Ошибка: " . $e->getMessage() . "\n"; $errors++; } } echo "\n=== РЕЗУЛЬТАТ ===\n"; echo "Исправлено: $fixed\n"; echo "Ошибок: $errors\n"; // Проверяем индексы echo "\n=== ПРОВЕРКА ИНДЕКСОВ ===\n"; $indexQuery = " SELECT DISTINCT TABLE_NAME, INDEX_NAME FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = ? AND TABLE_NAME LIKE 'oc_%' AND COLLATION = 'utf8mb3_general_ci' "; $indexStmt = $pdo->prepare($indexQuery); $indexStmt->execute([$dbName]); $indexes = $indexStmt->fetchAll(PDO::FETCH_ASSOC); if (!empty($indexes)) { echo "⚠️ Найдено индексов с неправильной collation: " . count($indexes) . "\n"; echo "Индексы нужно пересоздать вручную или через Nextcloud\n"; } else { echo "✅ Все индексы имеют правильную collation\n"; } } catch (PDOException $e) { echo "❌ Ошибка подключения к БД: " . $e->getMessage() . "\n"; exit(1); }