SQL Server — создание индексированного представления с привязкой к схеме с текущим фильтром GetDate

Я хочу создать следующее индексированное представление:

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);

Это прекрасно работает. Однако то, что я действительно хотел бы сделать, это включить в это представление только те строки, которые старше двух дней или новее, на текущую дату/время, когда запрашивается представление. Я не могу найти способ сделать это, потому что я не могу использовать GetDate() в предикате Where, потому что он недетерминирован. Другими словами, я хотел бы сделать что-то подобное, но не могу:

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

Есть ли способ обойти это?


person Randy Minder    schedule 07.10.2011    source источник


Ответы (1)


Насколько я знаю, вы не сможете обойти детерминированную функцию для требования SCHEMABINDING. Вы всегда будете получать сообщение об ошибке

Функция getdate дает недетерминированные результаты. Используйте детерминированную системную функцию или измените пользовательскую функцию, чтобы она возвращала детерминированные результаты.

Если Marker — это всего лишь одна таблица, я не уверен, что индексированное представление будет иметь какое-либо преимущество в производительности по сравнению с обычным представлением по сравнению с таблицей с тем же кластеризованным индексом в базовой таблице (ReadTime, EquipmentID).

Однако, если «Маркер» сам по себе является составным, таким как VIEW, ИЛИ, если вы не хотите изменять кластеризованный индекс в таблице маркеров, вы можете подумать о чем-то вроде:

  • Создайте представление с привязкой к схеме без фильтра ReadDate (vwMarker)
  • Создайте индексированное представление в нефильтрованном представлении
  • Создайте второе, не привязанное к схеме представление vwMarkerRecent или подобное, которое добавляет недетерминированный фильтр GetDate.

пример Sql Fiddle здесь

то есть что-то вроде:

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
person StuartLC    schedule 07.10.2011