次のコードを使用してインデックス付きビューを作成しようとしています(それをテーブルとしてレプリケーションにパブリッシュできるように)。
_CREATE VIEW lc.vw_dates
WITH SCHEMABINDING
AS
SELECT DATEADD(day, DATEDIFF(day, 0, GETDATE()), number) AS SettingDate
FROM lc.numbers
WHERE number<8
GO
CREATE UNIQUE CLUSTERED INDEX
idx_LCDates ON lc.vw_dates(SettingDate)
_
lc.numbersは、1列(number
)を1行100ずつ増やしたテーブルです。
ただし、エラーが発生し続けます。
ビュー 'lc.vw_dates'の列 'SettingDate'は、非決定的であるため、インデックスまたは統計で、またはパーティションキーとして使用できません。
GETDATE()
は非決定的であることを理解しています。しかし、カレンダーテーブルを描画せずにこれを機能させる方法はありますか?
関数の出力は時々刻々と変化するため、永続ビューの関数として関数GETDATE()
を使用することはできません。これは、SQL Serverがエラーで「非決定的であるため」という意味です。関数の結果は、SQL Serverが結果を保持するために、呼び出されるたびに予測可能に同じでなければなりません。
幸い、スケジュールされたジョブを使用して、このデータを1日に1回保持する簡単な方法があります。おそらく、SQL Serverエージェント、またはWindowsジョブスケジューラなどを使用しています。
ここでは、数値テーブルと、次の7日間を保持するテーブルを作成しています。
CREATE TABLE dbo.Numbers
(
Number INT NOT NULL
CONSTRAINT PK_Numbers
PRIMARY KEY CLUSTERED
);
;WITH cte AS
(
SELECT TOP(100) Number = ROW_NUMBER() OVER (ORDER BY t1.num, t2.num)
FROM (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t1(num)
, (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) t2(num)
ORDER BY t1.num * t2.num
)
INSERT INTO dbo.Numbers (Number)
SELECT cte.Number
FROM cte;
CREATE TABLE dbo.Next7Days
(
SettingDate DATETIME NOT NULL
CONSTRAINT PK_Next8Days
PRIMARY KEY CLUSTERED
);
これを1日に1回発生するようにスケジュールします。
TRUNCATE TABLE dbo.Next7Days;
INSERT INTO dbo.Next7Days(SettingDate)
SELECT SettingDate = DATEADD(DAY, n.Number, DATEDIFF(DAY, 0, GETDATE()))
FROM dbo.Numbers n
WHERE n.Number < 8;
次の7日間の日付は1日に1回しか変更されないため、このソリューションは適切に機能するはずです。
dbo.Next7Days
テーブルには、上記のコードを実行した後の次のものが含まれています。