Một chức năng không nhất thiết phải xác định hoặc không xác định. Có một số chức năng có thể xác định tùy thuộc vào cách chúng được sử dụng :
Các hàm sau không phải luôn luôn xác định, nhưng có thể được sử dụng trong các khung nhìn hoặc chỉ mục được lập chỉ mục trên các cột được tính khi chúng được chỉ định theo cách xác định.
CASTvà CONVERTlà những ví dụ như vậy. Dựa trên thử nghiệm mà bạn đã thực hiện cho đến nay, tôi nghĩ rằng thật công bằng khi nói rằng điều đó FORMATkhông phải lúc nào cũng mang tính quyết định, mặc dù là một hàm chuỗi. Nếu bạn muốn biết liệu đôi khi nó mang tính quyết định, kỹ thuật duy nhất tôi có thể nghĩ đến là thử đủ các cách khác nhau để gọi nó cho đến khi bạn hài lòng. Ví dụ, hãy xem xét FORMATnhư áp dụng cho số. Chỉ có mười loại đầu vào số khác nhau :

Cũng có chín định dạng số khác nhau . Có thể cố gắng tạo các cột bền vững cho tất cả các kết hợp có thể. Một số mã để làm điều đó là dưới đây:
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;
Đây là một mẫu của đầu ra:

Tôi không thể có bất kỳ cột nào được thêm vào bảng cho một vài giá trị và văn hóa đầu vào. Tôi đã không thử triệt để tất cả các nền văn hóa có thể bởi vì tôi không thể tìm thấy danh sách của chúng trong SQL Server.
Tối thiểu có vẻ an toàn để kết luận rằng tài liệu liên quan đến tính xác định FORMATlà không chính xác, vì vậy tôi khuyên bạn nên gửi một mục kết nối cho nó.
alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;. Không chắc chắn tại saoFORMATkhông mang tính quyết định, đặc biệt là khi chỉ định văn hóa. Cácdate_formattedcột có thể đượcVARCHAR(20)(vẫn kiên trì) và thiết lập thông qua kích hoạt sử dụngFORMAT. Hoặc SQLCLR hoạt động. Sử dụng thư viện SQL # SQLCLR (mà tôi đã viết), bạn có thể làm đượcALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;(bảng được sở hữu bởi SQL # do chủ sở hữu bảng và hàm cần phải giống nhau).