在索引视图中使用FORMATMESSAGE

时间:2019-03-13 10:44:51

标签: sql-server tsql

在创建使用内置函数FORMATMESSAGE的索引视图时,出现错误(如下所示),即FORMATMESSAGE是不确定的。可以理解,该视图无法实现,这大概是因为FORMATMESSAGE的输出取决于本地化信息,因此对于相同的参数并不总是提供相同的输出。

我试图找到一种方法,将特定的语言环境传递给FORMATMESSAGE,使其使用sys.messages而不是原义格式字符串来确定性,但没有成功。

但是,关于Deterministic and Nondeterministic Functions的最新MS信息并没有具体说明FORMATMESSAGE是非确定性的。因此,

有没有人找到在索引视图中使用FORMATMESSAGE的方法?

这是我的简化测试代码:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
        <packagingExcludes>WEB-INF/lib/websocket-*.jar</packagingExcludes>
    </configuration>
</plugin>

到目前为止,太好了。 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 ---------------------------------------------------------------- 产生正确的结果:

Results

但是,这样做的全部目的是使视图建立索引(这样就可以实现该视图,即,结果是预先计算的,并由SQL Server保留在视图中-Speed,伙计!)。但是,

SELECT * FROM dbo.vwExtensions

出现错误:

CREATE UNIQUE CLUSTERED INDEX IX_Extension ON dbo.vwExtensions (ID)

注意:我正在寻找计算列解决方案,因为其他原因在这里并不重要。 (出于与上述完全相同的原因,在任何情况下都不允许将计算列的Cannot create index on view 'TEST_DB.dbo.vwExtensions'. The function 'formatmessage' yields nondeterministic results. Use a deterministic system function, or ... 属性设置为true)。

编辑:应该在此处添加-我需要使用FORMATMESSAGE(或某些确定性替代方法),而不是CONCAT(RIGHT(...等),因为格式字符串也存储在表中,而不是如此处所示的硬编码。上面我的代码的简化版本并未表明这一点。

1 个答案:

答案 0 :(得分:1)

尝试使用确定性函数:

CREATE VIEW dbo.vwExtensions
WITH SCHEMABINDING AS

  SELECT
    ID,
    CONCAT(Name, ' Extension', ' '
        , RIGHT('000' + CAST(ExtNo AS VARCHAR(3)), 3)) AS ExtensionName
  FROM
    dbo.Extensions

然后创建索引:

CREATE UNIQUE CLUSTERED INDEX IX_Extension ON dbo.vwExtensions (ID)