Mengapa saya memiliki beberapa tabel sejarah temporal (tidak berhubungan)?

8

Saya telah menyiapkan bukti konsep sistem yang memiliki ujung belakang SQL Server 2017.
Sistem menggunakan tabel temporal untuk mencatat konfigurasi aset dan melacak perubahan dari waktu ke waktu.
Saya memiliki tabel Data yang ditautkan ke tabel riwayat, sebut saja dbo.MSSQL_TemporaryHistoryFor_12345678900.

Sejauh ini bagus. Saya punya dua masalah:

Hari ini saya mematikan versi di atas meja sehingga saya bisa menambahkan kolom yang dihitung. Ini dilakukan dan dihidupkan kembali lagi tanpa kesalahan.

Sekarang saya menemukan bahwa saya tidak dapat meminta data historis apa pun dari sebelum perubahan. Data baru sedang ditambahkan ke histori, tetapi sebelumnya tidak ada.

Melihat ke dalam SSMS, sekarang saya bisa melihat ada beberapa tabel histori, semua dengan nama yang sama tetapi dengan akhiran hex, misalnya dbo.MSSQL_TentaraHistoryFor_12345678900_A0B1C2D3. Mereka tidak tertaut di bawah tabel data utama. Mereka hanya mengambang di dalam database mereka sendiri. Ketika saya tanya sys.tables, ini tidak ditampilkan sebagai tabel histori dan tidak ditautkan ke tabel data utama.

Tabel ini berisi data historis yang tidak ada.

Pertanyaan yang saya miliki adalah:

  • Apa yang diwakili tabel tambahan ini?
  • Bagaimana mereka diciptakan?
  • Apakah ada cara untuk menghubungkan kembali ini ke dalam rantai sejarah utama sehingga saya bisa mendapatkan pelaporan historis saya kembali?

Ini sangat menyebalkan sehingga bantuan apa pun yang dapat Anda berikan akan diterima dengan penuh syukur. Terima kasih.

MrB
sumber
1
Mungkin bermanfaat jika Anda memberikan perintah yang Anda jalankan sebelum masuk ke kondisi ini.
LowlyDBA

Jawaban:

8

Anda harus memberikan nama tabel histori untuk menjaga kesinambungan data saat mematikan dan menghidupkan versi sistem. Perilaku ini disebutkan dalam dokumentasi untuk ALTER TABLE :

Jika Anda tidak menggunakan argumen HISTORY_TABLE, sistem menghasilkan tabel riwayat baru yang cocok dengan skema tabel saat ini, membuat tautan antara dua tabel, dan memungkinkan sistem untuk merekam sejarah setiap catatan dalam tabel saat ini di tabel sejarah.

Ini demo. Saya akan membuat tabel contoh dari dokumentasi:

CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON);

Ini menghasilkan tabel sejarah bernama MSSQL_TemporalHistoryFor_1253579504. Sekarang saya akan menonaktifkan dan mengaktifkan versi sistem:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON);

Dan saya dalam situasi persis Anda:

masukkan deskripsi gambar di sini


Sekarang saya akan membersihkan semuanya:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
DROP TABLE dbo.Employee;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504;
DROP TABLE dbo.MSSQL_TemporalHistoryFor_1253579504_D0055BB4;

Kemudian buat tabel dengan nama tabel riwayat spesifik:

 CREATE TABLE dbo.Employee   
(    
  [EmployeeID] int NOT NULL PRIMARY KEY CLUSTERED   
  , [Name] nvarchar(100) NOT NULL  
  , [Position] varchar(100) NOT NULL   
  , [Department] varchar(100) NOT NULL  
  , [Address] nvarchar(1024) NOT NULL  
  , [AnnualSalary] decimal (10,2) NOT NULL  
  , [ValidFrom] datetime2 (2) GENERATED ALWAYS AS ROW START  
  , [ValidTo] datetime2 (2) GENERATED ALWAYS AS ROW END  
  , PERIOD FOR SYSTEM_TIME (ValidFrom, ValidTo)  
 )    
 WITH (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));  

Kemudian, matikan dan matikan versi sistem, tetapi lanjutkan tentukan nama tabel histori:

ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = OFF);
ALTER TABLE dbo.Employee SET (SYSTEM_VERSIONING = ON (HISTORY_TABLE = dbo.EmployeeHistory));

Catatan: dalam situasi spesifik Anda, Anda harus dapat menggunakan sintaks ini untuk "memasang kembali" satu tabel histori yang hilang ke tabel dasar Anda

Tidak ada meja tambahan:

masukkan deskripsi gambar di sini

Dibawa pulang

Selalu tentukan nama tabel riwayat secara eksplisit saat membuat tabel temporal atau mengaktifkan versi sistem.

Dokumen MS sekarang menyebutkan ini secara khusus pada Menghentikan Versi-Sistem pada halaman Tabel Temporal Versi Sistem :

Saat mengaktifkan versi sistem kembali, jangan lupa untuk menentukan argumen HISTORY_TABLE. Gagal melakukannya akan menghasilkan tabel sejarah baru yang dibuat dan dikaitkan dengan tabel saat ini. Tabel riwayat asli masih akan ada sebagai tabel normal, tetapi tidak akan dikaitkan dengan tabel saat ini.

Josh Darnell
sumber