benutzerdefinierte function (TSQL) nicht deterministische und berechnete persistierte Spalte

Ich habe einen Tisch, der unter den Spalten gibt es zwei Spalten Typ Typ INT und sie heißen:

 ExpirationMonth 

und

 ExpirationYear 

Ich möchte eine neue Spalte zu dieser Tabelle hinzufügen, deren Wert auf der Grundlage der Werte von ExpirationMonth und ExpirationYear berechnet wird. Also diese Spalte wäre eine berechnete Spalte.

Zu diesem Zweck habe ich eine benutzerdefinierte Skalarfunktion erstellt, die den Wert dieser Spalte anhand der Werte von ExpirationMonth und ExpirationYear berechnet. Die Definition der function ist folgende:

 CREATE FUNCTION [dbo].[IsExpired] ( @ExpirationMonth INT, @ExpirationYear INT ) RETURNS BIT AS BEGIN DECLARE @Today DATE = GETDATE() DECLARE @PreviousMonth INT = MONTH(@today)-1 DECLARE @CurrentYear INT = YEAR(@today) DECLARE @IsExpired BIT = 0 IF(@ExpirationYear<@CurrentYear OR (@ExpirationYear=@CurrentYear AND @ExpirationMonth<=@PreviousMonth)) SET @IsExpired = 1 RETURN @IsExpired END 

Zuerst habe ich versucht, die Spalte wie unten hinzuzufügen:

 ALTER Table_Name ADD IsExpired AS [dbo].[IsExpired]([ExpirationMonth], [ExpirationYear]) PERSISTED 

Und ich habe folgende Fehlermeldung:

Die berechnete Spalte 'IsExpired' in der Tabelle 'Table_Name' kann nicht beibehalten werden, da die Spalte nicht deterministisch ist.

Ich habe die PERSISTED aus der obigen Aussage entfernt und ich lief es wieder. Dann bemerkte ich, dass die Spalte mit den erwarteten Werten hinzugefügt worden war.

Meine Frage ist, wie kann ich diese Spalte behalten, wenn das überhaupt möglich ist?

Ich erkannte, dass der Grund für diesen Fehler die Verwendung der GETDATE function in der IsExpired function ist. Da GETDATE nicht deterministisch ist, ist das IsExpired nicht deterministisch.

Allerdings sehe ich nicht, wie wir diese function machen können, IsExpired , um deterministisch zu sein und damit die berechnete Spalte als beharrlich zu definieren, wenn das überhaupt möglich ist.

Könnten Sie mir bitte sagen, ob das möglich ist und ob es so ist, wie kann ich das machen?

Der Wert ist nicht deterministisch, weil er vom aktuellen date abhängig ist. Sie können nicht berechnete Spalten bestehen, deren Werte sich im Laufe der time ändern können.

Sehen Sie diesen Artikel auf MSDN für weitere Informationen über Deterministic Functions.

Ich würde es vorschlagen, es in einer view zu machen

 SELECT * INTO yourTable FROM (VALUES(2015,1),(2015,2),(2015,3),(2015,4),(2015,5),(2015,6)) AS A(ExpirationYear,ExpirationMonth); GO CREATE VIEW vw_Expiration AS SELECT ExpirationYear, ExpirationMonth, CASE WHEN ExpirationYear < YEAR(GETDATE()) OR (ExpirationYear = YEAR(GETDATE()) AND ExpirationMonth <= MONTH(GETDATE())) THEN 1 ELSE 0 END AS IsExpired FROM yourTable; GO SELECT * FROM vw_Expiration 

Ergebnisse:

 ExpirationYear ExpirationMonth IsExpired -------------- --------------- ----------- 2015 1 1 2015 2 1 2015 3 1 2015 4 1 2015 5 0 2015 6 0