2017-08-17 138 views
0

我试图为cdc函数的结果创建索引视图。原始查询很大且很复杂。下面是产生同样的错误查询的简化版本:我使用dbocdc是否可以为使用CDC功能的查询创建“索引视图”?

Cannot schema bind view 'dbo.view_Test'. 'cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh' is not schema bound.

,我读了

if you want to create an index on a view or you want to preserve the base table schema once a view has been defined, in both these cases you have to use the "WITH SCHEMABINDING" clause to bind the view to the schema of the base tables

在原来的查询:

SET NUMERIC_ROUNDABORT OFF; 
SET ANSI_PADDING, ANSI_WARNINGS, CONCAT_NULL_YIELDS_NULL, ARITHABORT, 
    QUOTED_IDENTIFIER, ANSI_NULLS ON; 
GO 
--Create view with schemabinding. 
IF OBJECT_ID ('dbo.view_Test', 'view') IS NOT NULL 
DROP VIEW dbo.view_Test; 
GO 
CREATE VIEW dbo.view_Test 
WITH SCHEMABINDING 
AS 

SELECT 
kz.__$start_lsn, 
    kz.__$seqval, 
    kz.__$operation AS operation, 
    kz.__$update_mask, 
    kz.GUID, 
    kz.typezalezh, 
    kz.category, 
    kz.zone, 
    kz.area, 
    kz.Volume 
FROM cdc.fn_cdc_get_all_changes_dbo_EXT_GeolObject_KategZalezh(sys.fn_cdc_get_min_lsn('dbo_EXT_GeolObject_KategZalezh'), sys.fn_cdc_get_max_lsn(), 'all') AS kz 
GO 

该查询返回如下因素误差模式在这里我只使用cdc模式。但我想在dbo dchema创建视图。 此外,我正在使用CDC功能,而不是像微软推荐的那样直接使用cdc表。

我读到一些事情要考虑创建索引视图时:

  • 不能创建与外视图索引联接在其使用,即使您使用架构绑定
  • 你可以在视图中的select语句不创建与外视图索引在它加入使用,即使您使用架构绑定
  • 不能使用“*”当它被绑定到架构。
  • 您将无法在视图上创建聚集索引,如果视图引用任何非确定性函数。
  • 使用模式绑定时不能使用聚合函数。
  • 您无法迁移模式绑定视图的基表。

据我所知,我的查询是适合这个规则。但我不确定CDC功能是确定性的还是非确定性的。

是一种可能创建查询“索引视图”,其中使用CDC功能?

回答

1

号,CDC功能不是“架构绑定”这样看来,这依赖于它,不能在所有的索引。相反,您可以创建一个表并定期从函数中填充它。

假设你表“testdb.dbo.Customers_for_cdc_test”这是CDC启用。您可以通过代码兑现CDC功能:

use testdb 
go 
select top (0) * 
    into dbo.SOURCE_NAME_changes 
    from cdc.fn_cdc_get_all_changes_dbo_Customers_for_CDC_test 
     (
     sys.fn_cdc_get_min_lsn('dbo_Customers_for_cdc_test') 
     , sys.fn_cdc_get_max_lsn() 
     , N'all' 
     ) as src 
; 
create index IX__dbo__SOURCE_NAME_changes 
    on dbo.SOURCE_NAME_changes 
    (
    __$start_lsn asc 
) 
; 
-- Other needed indices can be here. 
go 

填表格可以作为作业来实现。设定工作时间表以便定期开始。工作本身可能只包含一个步骤调用填充过程

use testdb 
go 
exec dbo.sp_append_new_SOURCE_NAME_changes 

其中“dbo.sp_append_new_SOURCE_NAME_changes”是

use testdb 
go 
create procedure dbo.sp_append_new_SOURCE_NAME_changes 
    as 
    begin 
    set nocount on 
    ; 
    declare @max_old_lsn as binary(10) 
      , @min_old_lsn as binary(10) 
      , @min_active_lsn as binary(10) = sys.fn_cdc_get_min_lsn('dbo_Customers_for_CDC_test') 
      , @max_active_lsn as binary(10) = sys.fn_cdc_get_max_lsn() 
    ; 
    select @max_old_lsn = coalesce(max(__$start_lsn) ,cast(0 as binary(10))) 
     , @min_old_lsn = coalesce(min(__$start_lsn) ,cast(0 as binary(10))) 
     from dbo.SOURCE_NAME_changes 
    ; 
    if (@min_old_lsn < @min_active_lsn 
    ) begin 
     delete from dbo.SOURCE_NAME_changes 
      where __$start_lsn < @min_active_lsn 
     ; 
     end 
    if (@max_old_lsn < @max_active_lsn 
    ) begin 
     declare @min_lsn as binary(10) = iif(@min_active_lsn < @max_old_lsn ,@max_old_lsn ,@min_active_lsn) -- Speed up 
     ; 
     insert into dbo.SOURCE_NAME_changes 
      --(COLUMN_LIST) 
      select * --(COLUMN_LIST) 
      from cdc.fn_cdc_get_all_changes_dbo_Customers_for_CDC_test 
       (
        @min_lsn 
       , @max_active_lsn 
       , N'all' 
       ) as src 
      where src.__$start_lsn > @max_old_lsn -- Because the max old lsn is already in. 
      ; 
     end 
    end 
go 
+0

谢谢。我想过这个问题。一个问题。我可以从简单视图创建索引视图吗? – Seva

+0

是的,您可以在视图符合某些限制时创建索引。限制和一个很好的例子可以在这里找到[链接](https://docs.microsoft.com/en-us/sql/relational-databases/views/create-indexed-views)。 –

相关问题