
Re: [MSSQL] Synchronizacja SQL z MYSQL w czasie rzeczywistym
ok ogarnięte
dodałem change_tracking w sql potem prosty skrypt php który wykonuje zrzut do bazy zdalnej z strukturą 1:1 (create, update, delete)
Kod:
public function executeXt(): Response
{
// Połączenie do MSSQL (default)
$mssql = \Cake\Datasource\ConnectionManager::get('symfonia');
// Połączenie do MySQL (baza240)
$mysql = \Cake\Datasource\ConnectionManager::get('zdalna');
// Sprawdzamy wersję zmian w MSSQL dla tabeli Xt
try {
$result = $mssql->execute("SELECT CHANGE_TRACKING_CURRENT_VERSION() AS version")->fetch('assoc');
$currentVersion = (int)($result['version'] ?? 0);
} catch (\Exception $e) {
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'error',
'message' => "Błąd podczas wykonywania zapytania: " . $e->getMessage()
]));
}
// Pobieramy zmienione rekordy z MSSQL (tabela Xt)
try {
$changedXt = $mssql->execute("
SELECT CT.id
FROM CHANGETABLE(CHANGES [HM].[Xt], ?) AS CT
", [0])->fetchAll('assoc');
} catch (\Exception $e) {
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'error',
'message' => "Błąd podczas pobierania zmienionych rekordów: " . $e->getMessage()
]));
}
if (empty($changedXt)) {
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'info',
'message' => 'Brak zmian w tabeli Xt od ostatniej synchronizacji.'
]));
}
// Rozpoczynamy transakcję w MySQL
$mysql->begin();
try {
// Synchronizacja zmienionych rekordów z MSSQL do MySQL
foreach ($changedXt as $change) {
$row = $mssql->execute("SELECT * FROM [HM].[Xt] WHERE id = ?", [$change['id']])->fetch('assoc');
if ($row) {
// Używamy backticków dla kolumn, które mogą być zarezerwowanymi słowami
$columns = array_keys($row);
$placeholders = implode(', ', array_map(fn($col) => ":$col", $columns));
$columnList = implode(', ', array_map(fn($col) => "`$col`", $columns)); // Dodajemy backticky
$sql = "REPLACE INTO Xt ($columnList) VALUES ($placeholders)";
$mysql->execute($sql, $row);
}
}
// Zatwierdzamy transakcję w MySQL
$mysql->commit();
} catch (\Exception $e) {
// W razie błędu, wycofujemy transakcję
$mysql->rollback();
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'error',
'message' => "Błąd podczas synchronizacji: " . $e->getMessage()
]));
}
// Zapisujemy wersję synchronizacji
try {
file_put_contents(LOGS . 'xt_sync_version.txt', $currentVersion);
} catch (\Exception $e) {
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'error',
'message' => "Błąd podczas zapisywania wersji synchronizacji: " . $e->getMessage()
]));
}
return $this->response->withType('json')->withStringBody(json_encode([
'status' => 'success',
'message' => 'Synchronizacja tabeli Xt zakończona.',
'currentVersion' => $currentVersion
]));
}

i wszystko puszczone w CRON co 5 minut