无法在架构绑定视图上创建索引

时间:2019-04-02 11:08:30

标签: sql-server-2012 subquery indexed-view

无法在下面的模式绑定视图上创建索引。它是从另一个视图(v_prod_manu_sub)创建的。它在下面的错误消息中显示'无法在视图“ dbo.V_PROD_MANU”上创建索引,因为它引用了派生表“ X”(由FROM子句中的SELECT语句定义)。考虑删除对派生表的引用 或不为视图编制索引。'如何在查询创建索引下方更改此内容??

ALTER VIEW [dbo].[V_PROD_MANU] WITH SCHEMABINDING AS
SELECT X.PRODUCT, CAST(RIGHT(TEXT_CODE,LEN(F_TEXT_CODE)-1) AS VARCHAR(30)) AS TEXT_CODE,
    CAST(SUBSTRING(RIGHT(PHRASE,LEN(F_PHRASES)-1),9,LEN(F_PHRASE)-3) AS varchar(700)) AS PHRASE
    FROM (
    SELECT V1.PRODUCT,
    (SELECT ',' + V2.TEXT_CODE FROM dbo.V_PROD_MANU_SUB V2 WHERE V1.PRODUCT = V2.PRODUCT ORDER BY V2.F_COUNTER  FOR XML PATH('')) AS TEXT_CODE,
    (SELECT ' |par|par ' + V3.F_PHRASE FROM dbo.V_PROD_MANU_SUB V3 WHERE V1.PRODUCT = V3.PRODUCT ORDER BY V3.F_COUNTER FOR XML PATH('')) AS PHRASE
FROM dbo.V_PROD_MANU_SUB  V1 GROUP BY V1.PRODUCT)X

输出

Product         TEXT_CODE                PHRASE 
00-021      MANU0043,MANU0050     Inc |par  Pharmaceuticals Group |par  235 East 5nd Street |par usa |par 1-800-123-000

1 个答案:

答案 0 :(得分:1)

通常,人们使用STUFF()删除前导逗号,而不是使用这些凌乱的转换和LEN()计算。例如:

SELECT V1.PRODUCT,
    TEXT_CODE = STUFF
    (
      (
        (SELECT ',' + V2.TEXT_CODE 
           FROM dbo.V_PROD_MANU_SUB AS V2 
           WHERE V1.PRODUCT = V2.PRODUCT 
           ORDER BY V2.F_COUNTER  
           FOR XML PATH, TYPE).value('.[1]','nvarchar(max)')
      ),
    1,1,N'')
FROM dbo.V_PROD_MANU_SUB AS V1 
GROUP BY V1.PRODUCT;

-- much easier in SQL Server 2017 with STRING_AGG()

但是,这似乎与为什么您首先需要具体化以逗号分隔的列表无关,无论它是否具有前导逗号。

索引视图通常是过早优化的一种形式。本质上,您是在说:“查询此数据的成本将远远大于维护数据的成本。”你知道吗?怎么样?您的工作量余额是多少(读:写)?现在查询有多慢?它多久运行一次?更新需要多长时间?

如果您确实知道这一点,那么可以通过触发器手动将其具体化到您自己的表中,这会更好。出于多种原因,索引视图很可能会死胡同。