Eine Funktion ist nicht unbedingt deterministisch oder nicht deterministisch. Es gibt einige Funktionen, die je nach Verwendung deterministisch sein können :
Die folgenden Funktionen sind nicht immer deterministisch, können jedoch in indizierten Ansichten oder Indizes für berechnete Spalten verwendet werden, wenn sie deterministisch angegeben werden.
CASTund CONVERTsind solche Beispiele. Basierend auf den Tests, die Sie bisher durchgeführt haben, denke ich, dass es fair ist zu sagen, dass dies FORMATnicht immer deterministisch ist, obwohl es sich um eine Zeichenfolgenfunktion handelt. Wenn Sie wissen möchten, ob es manchmal deterministisch ist, kann ich mir nur vorstellen, genug verschiedene Methoden auszuprobieren, um es zu nennen, bis Sie zufrieden sind. Betrachten wir zum Beispiel, FORMATwie es auf Zahlen angewendet wird. Es gibt nur zehn verschiedene numerische Eingabetypen :

Es scheint auch nur neun verschiedene numerische Formate zu geben . Es ist möglich, dauerhafte Spalten für alle möglichen Kombinationen zu erstellen. Ein Code dafür ist unten:
DECLARE @FormatValue INT = 76767; -- change this if you want
DECLARE @FormatCulture VARCHAR(10) = 'en-US'; -- change this if you want
DECLARE @Format VARCHAR(1);
DECLARE @FormatType VARCHAR(10);
DECLARE @SQLForColumn VARCHAR(200);
DECLARE @TestNumber INT = 0;
BEGIN
DROP TABLE IF EXISTS dbo.TargetTable;
CREATE TABLE dbo.TargetTable (ID INT);
DROP TABLE IF EXISTS #ColumnAddResults;
CREATE TABLE #ColumnAddResults (
FormatType VARCHAR(10),
[Format] VARCHAR(1),
Succeeded VARCHAR(1),
ErrorMessage VARCHAR(1000)
);
drop table if exists #Types;
create table #Types (FormatType VARCHAR(10));
INSERT INTO #Types VALUES
('bigint'), ('int'), ('smallint'), ('tinyint'), ('decimal')
, ('numeric'), ('float'), ('real'), ('smallmoney'), ('money');
drop table if exists #Formats;
create table #Formats ([Format] VARCHAR(1));
INSERT INTO #Formats VALUES
('C'), ('D'), ('E'), ('F'), ('G'), ('N'), ('P'), ('R'), ('X');
DECLARE format_statements CURSOR LOCAL FAST_FORWARD FOR
SELECT #Types.FormatType, #Formats.[Format]
FROM #Formats
CROSS JOIN #Types;
OPEN format_statements;
FETCH NEXT FROM format_statements
INTO @FormatType, @Format;
WHILE @@FETCH_STATUS = 0
BEGIN
SET @TestNumber = @TestNumber + 1;
SET @SQLForColumn = 'alter table dbo.TargetTable add NewColumn' + CAST(@TestNumber AS VARCHAR(10))
+ ' as FORMAT(CAST(' + CAST(@FormatValue AS VARCHAR(10)) + ' AS ' + @FormatType + '), '
+ '''' + @Format + ''', ''' + @FormatCulture + ''') persisted';
BEGIN TRY
EXEC (@SQLForColumn);
INSERT INTO #ColumnAddResults VALUES (@FormatType, @Format, 'Y', NULL);
END TRY
BEGIN CATCH
INSERT INTO #ColumnAddResults VALUES (@FormatType, @Format, 'N', ERROR_MESSAGE());
END CATCH;
PRINT @SQLForColumn;
FETCH NEXT FROM format_statements
INTO @FormatType, @Format;
END;
CLOSE format_statements;
DEALLOCATE format_statements;
SELECT * FROM dbo.TargetTable;
SELECT * FROM #ColumnAddResults;
DROP TABLE #ColumnAddResults;
END;
Hier ist ein Beispiel für die Ausgabe:

Ich konnte keine der Spalten für einige Eingabewerte und Kulturen zur Tabelle hinzufügen. Ich habe nicht alle möglichen Kulturen ausführlich ausprobiert, da ich in SQL Server keine Liste finden kann.
Zumindest scheint es sicher zu sein, dass die Dokumentation bezüglich des Determinismus von FORMATfalsch ist, daher würde ich empfehlen, ein Verbindungselement dafür einzureichen.
alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;. Ich bin mir nicht sicher, warumFORMATdas nicht deterministisch ist, besonders wenn ich die Kultur spezifiziere. Diedate_formattedSpalte kann seinVARCHAR(20)(noch anhielt) und stellen Sie über TriggerFORMAT. Oder SQLCLR funktioniert. Mit der SQL # SQLCLR-Bibliothek (die ich geschrieben habe) können Sie dies tunALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;(Tabelle gehört SQL #, da Tabelle und Funktionseigentümer identisch sein müssen).