私はSQL Serverのテンポラルテーブルを使用していて、生成された時間はUTC datetime2のトランザクション開始時間です
SQL Serverに同じトランザクションの開始時間を取得するための関数またはテーブルはありますか?最初にシステムバージョン対応テーブルに書き込み、そこから選択する必要のない他の場所で使用できますか?
同じトランザクションの一部である非システムバージョンのテーブルがいくつかあります。SysUTCDateTime
を使用して変化させるのではなく、それらに対して記録されたdatetime2が一致するようにしたいです。
私はsys.dm_tran_active_transactions
からプルしようとしましたが、その日時とローカルサーバーの時間も異なっているようです。
システムのバージョン管理:2017-04-11 14:00:59.4690673
アクティブなトランザクション:2017-04-11 15:00:59.467
トランザクションの開始時にSELECT SYSUTCDATETIME();
の結果を保存する以外に、トランザクションの開始日をdatetime2として確実に取得する方法がわかりません。
ただし、回避策として、次の例のように、テンポラルテーブルの自動生成された行の開始日を返すことができます。
最初に、システムバージョンのテンポラルテーブルを作成します。
IF OBJECT_ID('dbo.TemporalTest', 'U') IS NOT NULL
BEGIN
ALTER TABLE dbo.TemporalTest SET (SYSTEM_VERSIONING = OFF);
DROP TABLE dbo.TemporalTest;
END
IF OBJECT_ID('dbo.TemporalTestHistory', 'U') IS NOT NULL
DROP TABLE dbo.TemporalTestHistory;
CREATE TABLE dbo.TemporalTestHistory
(
TemporalTestID int NOT NULL
, RowStartDate datetime2 NOT NULL
, RowEndDate datetime2 NOT NULL
, SomeData varchar(100) NOT NULL
) ON [PRIMARY];
CREATE CLUSTERED INDEX CX_TemporarlTestHistory
ON dbo.TemporalTestHistory(TemporalTestID, RowStartDate, RowEndDate);
CREATE TABLE dbo.TemporalTest
(
TemporalTestID int NOT NULL IDENTITY(1,1)
CONSTRAINT PK_TemporalTest
PRIMARY KEY CLUSTERED
WITH (DATA_COMPRESSION = PAGE
, ALLOW_ROW_LOCKS = ON
, ALLOW_PAGE_LOCKS = ON
, FILLFACTOR = 100
, PAD_INDEX = OFF
)
, RowStartDate datetime2 GENERATED ALWAYS AS ROW START HIDDEN NOT NULL
, RowEndDate datetime2 GENERATED ALWAYS AS ROW END HIDDEN NOT NULL
, PERIOD FOR SYSTEM_TIME (RowStartDate, RowEndDate)
, SomeData varchar(100) NOT NULL
) ON [PRIMARY]
WITH (
SYSTEM_VERSIONING = ON (
HISTORY_TABLE = dbo.TemporalTestHistory
, DATA_CONSISTENCY_CHECK = ON
)
);
GO
次に、システムバージョン対応テーブルに行を挿入し、その行を変更し、最後に挿入された開始日を表示するトランザクション:
BEGIN TRANSACTION;
DECLARE @t TABLE
(
RowStartDate datetime2 NOT NULL
);
INSERT INTO dbo.TemporalTest (SomeData)
OUTPUT inserted.RowStartDate
INTO @t (RowStartDate)
VALUES ('Max');
UPDATE dbo.TemporalTest SET SomeData = 'Max2' WHERE TemporalTestID = 1;
SELECT tt.TemporalTestID
, tt.SomeData
, tt.RowStartDate
, tt.RowEndDate
FROM dbo.TemporalTest tt
UNION ALL
SELECT tth.TemporalTestID
, tth.SomeData
, tth.RowStartDate
, tth.RowEndDate
FROM dbo.TemporalTestHistory tth
SELECT TOP(1) StartDate = t.RowStartDate
FROM @t t;
COMMIT TRANSACTION;
結果:
+ ---------------- + ---------- + --------------------- -------- + ----------------------------- + | TemporalTestID | SomeData | RowStartDate | RowEndDate | + ---------------- + ---------- + -------------- --------------- + ----------------------------- + | 1 | Max2 | 2017-04-11 17:39:29.5290911 | 9999-12-31 23:59:59.9999999 | | 1 |マックス| 2017-04-11 17:39:29.5290911 | 2017-04-11 17:39:29.5290911 | + ---------------- + ---------- + ----- ------------------------ + ------------------------- ---- + + ----------------------------- + | StartDate | + ----------------------------- + | 2017-04-11 17:39:29.5290911 | + ----------------------------- +
テーブル変数@tには、テンポラルテーブルに挿入された各行の行が含まれます。これを使用して、行の開始日を取得します。
私もこれに興味があります。
sys.dm_tran_current_transaction
を使用してAFAICTを実行すると、現在のトランザクションのIDを取得できます。
次に、sys.dm_tran_active_transactions
を使用すると、transactions_begin_timeですべてのトランザクションを取得できます