T-SQL:UNION ALL 视图不可更新,因为未找到分区列

Posted

技术标签:

【中文标题】T-SQL:UNION ALL 视图不可更新,因为未找到分区列【英文标题】:T-SQL : UNION ALL view not updatable because a partitioning column was not found 【发布时间】:2014-04-22 10:13:04 【问题描述】:

如何在有日期限制的视图中插入?

这是单击脚本作为创建表后生成的表:

Table 1:

CREATE TABLE [dbo].[tbl_zaua_1_17](
    [id] [int] NOT NULL,
    [date] [datetime] NULL,

     CONSTRAINT [PK_tbl_zaua_1_17] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[tbl_zaua_1_17]  
WITH CHECK ADD  CONSTRAINT [CK_tbl_zaua_1_17] 

CHECK  (([date]<'2014-01-18 00:00:00.000' AND [date]>'2014-01-16 00:00:00.000'))
GO

ALTER TABLE [dbo].[tbl_zaua_1_17] CHECK CONSTRAINT [CK_tbl_zaua_1_17]
GO`

Table 2:

CREATE TABLE [dbo].[tbl_zaua_1_11](
    [id] [int] NOT NULL,
    [date] [datetime] NULL,
 CONSTRAINT [PK_tbl_zaua_1_11] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[tbl_zaua_1_11]  WITH CHECK ADD  CONSTRAINT [CK_tbl_zaua_1_11] CHECK  (([date]<'2014-01-12 00:00:00.000' AND [date]>'2014-01-10 00:00:00.000'))
GO

ALTER TABLE [dbo].[tbl_zaua_1_11] CHECK CONSTRAINT [CK_tbl_zaua_1_11]
GO`

视图创建:

create view zaua1
as
   select * from [dbo].[tbl_zaua_1_11]
   union all
   select * from [dbo].[tbl_zaua_1_17]`

插入给出错误:

UNION ALL 视图不可更新,因为未找到分区列。

insert into [dbo].[zaua1]
values (3,'2014-01-11')

【问题讨论】:

Using Partitioned Views: "要对分区视图执行更新,分区列必须是基表主键的一部分。" (这里,“更新”被用于更广泛意义上的INSERTUPDATEDELETEMERGE,而不仅仅是UPDATE 可能是检查约束的问题,您也可以检查一下您的检查约束 CHECK (([date] '2014-01-10 00:00:00.000')) @marc_s - 嗯?我很清楚,这两个检查约束应该意味着一行只能属于这些表中的一个,而不能属于另一个。日期范围不同。 【参考方案1】:

这个例子可以解决你的问题

create table partA
    (
    partId int,
    type varchar(10) constraint CKpartA_type check (type = 'partA'),
    value int,
    constraint PKpartA primary key(partId, type),
    )
    create table partB
    (
    partId int,
    type varchar(10) constraint CKpartB_type check (type = 'partB'),
    value int,
    constraint PKpartB primary key(partId, type)
    )
    go
    create view part
    as
    select partId, type, value
    from partA
    union all
    select partId, type, value
    from partB
    go


    insert into part
    select 1,'partB',1
    union all
    select 2,'partA',2
    go
    update part
    set value = 20
    go

    select *
    from part

    go
    delete from part
    go

【讨论】:

谢谢。所以基本上你需要在分区表的主键中设置一个固定值?【参考方案2】:

现在我明白了,应该在两列(id、日期)上都设置了主键。

CREATE TABLE [dbo].[tbl_zaua_1_11](
    [id] [int] NOT NULL,
    [date] [datetime] NOT NULL,
 CONSTRAINT [PK_tbl_zaua_1_11] PRIMARY KEY CLUSTERED 
(
    [id] ASC,
    [date] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[tbl_zaua_1_11]  WITH CHECK ADD  CONSTRAINT [CK_tbl_zaua_1_11] 

CHECK  (([date]<'2014-01-12 00:00:00.000' AND [date]>'2014-01-10 00:00:00.000'))
GO

ALTER TABLE [dbo].[tbl_zaua_1_11] CHECK CONSTRAINT [CK_tbl_zaua_1_11]
GO

还是谢谢!

【讨论】:

从技术上讲,间隔不正确......它应该在一端大于或等于:(([日期] ='2014-01-11 00:00:00.000'))

以上是关于T-SQL:UNION ALL 视图不可更新,因为未找到分区列的主要内容,如果未能解决你的问题,请参考以下文章

T-SQL谜题:将表的每一行作为内联函数的输入传递,并使用UNION ALL开发新的堆栈数据集

UNION ALL vs UNION 用于更新/返回+选择?

MySQL中使用union all获得并集的排序

SQL视图提示无法使用Union all求大神帮忙

使用多个 UNION ALL 构建视图:有更好的方法吗?

当我的视图包含 UNION ALL 时,如何让 Oracle 使用索引?