Not able to create index on below schema binding view.It is created from another view (v_prod_manu_sub
).It is showing below error message:
Cannot create index on view "dbo.V_PROD_MANU" because it references derived table "X" (defined by SELECT statement in FROM clause). Consider removing the reference to the derived table or not indexing the view.
How to change this below query for index creation ?
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
OUTPUT:
Product TEXT_CODE PHRASE
00-021 MANU0043,MANU0050 Inc |par Pharmaceuticals Group |par 235 East 5nd Street |par usa |par 1-800-123-000
Typically people use STUFF()
to remove a leading comma, instead of these messy converts and LEN()
calculations. For example:
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('./text()[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()
But that doesn't seem to have anything to do with why you need to materialize the comma-separated list in the first place, whether it has a leading comma or not.
Indexed views are often a form of premature optimization. Essentially you're saying, "the cost of querying this data will be far greater than the cost of maintaining it." Do you know that? How? What is your workload balance (read:write)? How slow is the query now? How often does it run? How long do updates take?
If you do know that, you will have better luck materializing it to your own table, manually, through a trigger. An indexed view is quite likely going to be a dead end for a variety of reasons.