ฟังก์ชั่นไม่จำเป็นต้องกำหนดหรือ nondeterministic มีฟังก์ชั่นบางอย่างที่สามารถกำหนดขึ้นอยู่กับการใช้งาน :
ฟังก์ชั่นต่อไปนี้ไม่ได้กำหนดไว้เสมอ แต่สามารถใช้ในมุมมองที่จัดทำดัชนีหรือดัชนีในคอลัมน์ที่คำนวณได้เมื่อมีการระบุในลักษณะที่กำหนด
CASTและCONVERTเป็นตัวอย่างดังกล่าว จากการทดสอบที่คุณทำมาจนถึงตอนนี้ฉันคิดว่ามันยุติธรรมที่จะบอกว่าFORMATมันไม่ได้ถูกกำหนดไว้เสมอแม้จะเป็นฟังก์ชั่นสตริง หากคุณต้องการทราบว่าบางครั้งมันเป็นเทคนิคที่กำหนดได้อย่างเดียวที่ฉันคิดได้ก็คือลองโทรหาวิธีอื่น ๆ จนกว่าคุณจะพอใจ ตัวอย่างเช่นลองพิจารณาFORMATใช้กับตัวเลข มีอินพุตตัวเลขที่แตกต่างกันเพียงสิบชนิด :

นอกจากนี้ยังปรากฏว่ามีเพียงเก้ารูปแบบตัวเลขที่แตกต่างกัน เป็นไปได้ที่จะพยายามสร้างคอลัมน์ที่คงอยู่สำหรับชุดค่าผสมที่เป็นไปได้ทั้งหมด รหัสที่ต้องทำมีดังต่อไปนี้:
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;
นี่คือตัวอย่างของผลลัพธ์:

ฉันไม่สามารถรับคอลัมน์ใด ๆ เพื่อเพิ่มลงในตารางสำหรับค่าอินพุตและวัฒนธรรมบางอย่าง ฉันไม่ได้ลองวัฒนธรรมที่เป็นไปได้ทั้งหมดอย่างละเอียดถี่ถ้วนเพราะฉันไม่พบรายการของพวกเขาภายใน SQL Server
อย่างน้อยก็มีความปลอดภัยที่จะสรุปว่าเอกสารเกี่ยวกับการกำหนดระดับFORMATไม่ถูกต้องดังนั้นฉันขอแนะนำให้ส่งรายการเชื่อมต่อ
alter table #t add date_formatted_01 as CONVERT(VARCHAR(20), FORMAT(date_col, 'YYYY', 'en-US')) persisted;นอกจากนี้ยังล้มเหลว: ไม่แน่ใจว่าทำไมFORMATไม่กำหนดโดยเฉพาะอย่างยิ่งเมื่อระบุวัฒนธรรมdate_formattedคอลัมน์สามารถจะVARCHAR(20)(ยังคงยืนกราน)FORMATและตั้งค่าผ่านทางโดยใช้ทริกเกอร์ หรือ SQLCLR ทำงาน การใช้ไลบรารีSQL # SQLCLR (ที่ฉันเขียน) คุณสามารถทำได้ALTER TABLE SQL#.t ADD date_formatted_03 AS SQL#.Date_Format(date_col, 'd', 'en-US') PERSISTED;(SQL เป็นเจ้าของตาราง # เนื่องจากเจ้าของตารางและฟังก์ชันต้องเหมือนกัน)