sql-serversql-server-2008indexed-view

SQL Server - Creating a Schema Bound Indexed View with a current GetDate filter


I want to create the following indexed view:

CREATE VIEW [Cic].[vwMarker] WITH SCHEMABINDING 
    AS

    Select
        SubId,
        marker.EquipmentID,
        marker.ReadTime,
        marker.CdsLotOpside,
        marker.CdsLotBackside,
        marker.CdteLotOpside,
        marker.CdTeLotBackside
    From dbo.Marker 
    Where dbo.Marker.ReadTime >= Convert(dateTime,'10/5/2011',120)
GO

CREATE UNIQUE CLUSTERED INDEX IX_vwMarker_ReadTime_EquipmentID 
       ON Cic.vwMarker (ReadTime, EquipmentID);

This works fine. However, what I would really like to do is to only include rows in this view that are two days old or newer, as of the current date/time the view is queried. I can't find a way to do this because I cannot use GetDate() in the Where predicate because it is non-deterministic. In other words, I'd like to do something like this, but cannot:

Where dbo.Marker.ReadTime >= Convert(dateTime,DateAdd(dd,-2,GetDate()) ,120)

Is there a way around this?


Solution

  • AFAIK you aren't going to get around the deterministic function for the SCHEMABINDING requirement. You'll always receive the error

    The function 'getdate' yields nondeterministic results. Use a deterministic system function, or modify the user-defined function to return deterministic results.

    If Marker is just a single table, I'm not sure that an indexed view would have any performance benefit over a normal view against the table with the same clustered index on the underlying table of (ReadTime, EquipmentID)

    However, if "Marker" is itself a composite such as a VIEW, OR if you don't want to change the Clustered Index on the Marker table, then you might consider something like:

    Sql Fiddle example here

    i.e. Something like:

    CREATE VIEW [Cic].[vwMarker] WITH SCHEMABINDING 
        AS
        Select
            SubId,
            marker.EquipmentID,
            marker.ReadTime,
            marker.CdsLotOpside,
            marker.CdsLotBackside,
            marker.CdteLotOpside,
            marker.CdTeLotBackside
        From dbo.Marker 
        -- Add only Deterministic where filters here
    GO
    
    CREATE UNIQUE CLUSTERED INDEX IX_vwMarker ON Cic.vwMarker (ReadTime, EquipmentID)
    GO    
    
    
    CREATE VIEW [Cic].[vwRecentMarker] -- Not Schema Bound
        AS
            Select
                vm.SubId,
                vm.EquipmentID,
                vm.ReadTime,
                vm.CdsLotOpside,
                vm.CdsLotBackside,
                vm.CdteLotOpside,
                vm.CdTeLotBackside
            From cic.vwMarker vm
            Where vm.ReadTime >= Convert(dateTime,DateAdd(dd,-2,GetDate()) ,120)
        GO