When creating an indexed view which uses the built-in function FORMATMESSAGE, I get an error (below), that FORMATMESSAGE is non-deterministic. Understandably, the view cannot be materialised, and this is presumably because the output of FORMATMESSAGE depends on localisation info, so doesn't always give the same output for the same parameters.
I've tried to find a way to pass a specific locale to FORMATMESSAGE to make it deterministic by using sys.messages instead of a literal format string, with no success.
However, the latest MS info about Deterministic and Nondeterministic Functions doesn't specifically say that FORMATMESSAGE is non-deteministic. Thus,
Has anyone found a way to use FORMATMESSAGE in an indexed view?
Here is my simplified test code:
SET ANSI_NULLS, QUOTED_IDENTIFIER, ANSI_PADDING ON
GO ----------------------------------------------------------------
CREATE TABLE dbo.Extensions(
ID INT IDENTITY(1,1) NOT NULL,
Name VARCHAR(50) NULL,
ExtNo INTEGER NOT NULL,
CONSTRAINT PK_Test PRIMARY KEY CLUSTERED (ID ASC)
)
GO ----------------------------------------------------------------
INSERT dbo.Extensions (Name, ExtNo)
VALUES ('New York', 55),
('San Francisco', 6),
('Paris', 4);
GO ----------------------------------------------------------------
CREATE VIEW dbo.vwExtensions
WITH SCHEMABINDING AS
SELECT
ID,
FORMATMESSAGE ('%s Extension %03i', Name, ExtNo) AS ExtensionName
FROM
dbo.Extensions
GO ----------------------------------------------------------------
So far, so good. SELECT * FROM dbo.vwExtensions
yields the correct results:
But the whole point of this is to make the view indexed (so it gets materialised, i.e. the results are calculated in advance and persisted in the view by SQL Server - Speed, man!). However,
CREATE UNIQUE CLUSTERED INDEX IX_Extension ON dbo.vwExtensions (ID)
gives an error:
Cannot create index on view 'TEST_DB.dbo.vwExtensions'. The function 'formatmessage' yields nondeterministic results. Use a deterministic system function, or ...
Note: I'm not looking for a computed column solution, for other reasons not important here. (That wouldn't allow the persisted
attribute of the computed column to be set true in any case, for exactly the same reasons as above).
Edit: Should add here - I need to use FORMATMESSAGE (or some deterministic alternative), rather than CONCAT (RIGHT (... etc, since the format string is also stored in a table, rather than hard-coded, as indicated here. The simplified version of my code above does not indicate that.