我收到了一个错误:
Msg 4406, Level 16, State 1, Line 5
Update or insert of view or function 'dbo.vwEmployeeAll' failed because it contains a derived or constant field.
然而,在我看来,我没有得出或不变。 我视图中的列都存在。在下面的例子中,这是相当简单的。
-- START TSQL
SET NOCOUNT ON
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'vwEmployeeAll' and TABLE_TYPE = N'VIEW' )
BEGIN
DROP VIEW [dbo].[vwEmployeeAll]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[EmployeeDeprecated]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Employee]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Department' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Department]
END
GO
CREATE TABLE [dbo].[Department](
[DepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[DepartmentName] [nvarchar](80) NULL,
[CreateDate] [datetime] NOT NULL
)
ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID])
GO
ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName])
GO
CREATE TABLE [dbo].[Employee] (
/* [EmployeeUUID] [uniqueidentifier] NOT NULL, */
[EmployeeSurrogateKey] int not null IDENTITY(1,2),
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeSurrogateKey)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_Employee_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [CK_Employee_PK_IsOdd] CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
CREATE TABLE [dbo].[EmployeeDeprecated] (
/*[EmployeeDeprecatedUUID] [uniqueidentifier] NOT NULL,*/
[EmployeeDeprecatedSurrogateKey] int not null IDENTITY(2,2),
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.[EmployeeDeprecated] ADD CONSTRAINT PK_EmployeeDeprecated PRIMARY KEY NONCLUSTERED (EmployeeDeprecatedSurrogateKey)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT CK_EmployeeDeprecated_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT FK_EmployeeDeprecatedToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[EmployeeDeprecated]
ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven] CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
CREATE VIEW dbo.vwEmployeeAll AS
Select
EmployeeSurrogateKey,ParentDepartmentUUID,TheVersionProperty,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.Employee
UNION --ALL
Select
/* EmployeeSurrogateKey = */
EmployeeDeprecatedSurrogateKey ,ParentDepartmentUUID,TheVersionProperty,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.EmployeeDeprecated
GO
declare @DepartmentUUID001 uniqueidentifier
select @DepartmentUUID001 = 'DDDDDDDD-0000-0000-0000-000000000101'
declare @DepartmentUUID002 uniqueidentifier
select @DepartmentUUID002 = 'DDDDDDDD-0000-0000-0000-000000000102'
INSERT INTO dbo.Department (DepartmentUUID , DepartmentName , CreateDate )
Select @DepartmentUUID001 , 'Department One' , CURRENT_TIMESTAMP
UNION
Select @DepartmentUUID002 , 'Department Two' , CURRENT_TIMESTAMP
/*
declare @EmployeeUUID001 uniqueidentifier
select @EmployeeUUID001 = 'EEEEEEEE-0000-0000-0000-000000001001'
declare @EmployeeUUID00A uniqueidentifier
select @EmployeeUUID00A = 'EEEEEEEE-0000-0000-AAAA-000000009001'
*/
INSERT INTO dbo.Employee (/*EmployeeUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate)
Select /*@EmployeeUUID001 ,*/ @DepartmentUUID001 , '111-11-1111' , 'Smith', 'John' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '01/01/2001'
INSERT INTO dbo.EmployeeDeprecated(/*EmployeeDeprecatedUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate)
Select /*@EmployeeUUID00A ,*/ @DepartmentUUID002 , '888-88-8888' , 'Jones', 'Mary' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '02/02/2002'
GO
Select * from dbo.vwEmployeeAll
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP
编辑:
时间戳将其抛出一个循环。
分区视图'ViewUpdateableDB.dbo.vwEmployeeAll'不可更新,因为表'[ViewUpdateableDB]。[dbo]。[Employee]'有一个时间戳列。
答案 0 :(得分:0)
当主键为Identity时,您无法在使用UNION的视图中更新数据。您必须有一个分区列。否则,它将如何知道要更新哪个表?
IE,您正在使用2个在标识字段上具有主键的表。两个表中的{PK} = 1都可以。 SQL Server如何知道要更新的表。
答案 1 :(得分:0)
这是一个有效的例子......" UNION ALL"和分区栏。
我发布这个,因为有一种特定的方式让它工作....尽管有msdn文档。
计算。无法从表达式计算列 使用其他列。使用set运算符形成的列 UNION,UNION ALL,CROSSJOIN,EXCEPT和INTERSECT等于a 计算,也不可更新。
http://msdn.microsoft.com/en-us/library/ms187956%28v=sql.110%29.aspx
根据文档和大多数情况,史蒂夫的答案是正确的,但通过使用分区列,有一种方法可以使其发挥作用。
下面的脚本/示例使用Developer Edition(没有许可的企业版),我针对SqlExpress进行了测试(Microsoft SQL Server 2012 - 11.0.2100.60(X64) Windows NT 6.1上的Express Edition(64位)(Build 7601:Service Pack 1) )
Select @@VERSION
-- START TSQL
SET NOCOUNT ON
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'vwEmployeeAll' and TABLE_TYPE = N'VIEW' )
BEGIN
DROP VIEW [dbo].[vwEmployeeAll]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[EmployeeDeprecated]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Employee]
END
GO
IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Department' and TABLE_TYPE = N'BASE TABLE' )
BEGIN
DROP TABLE [dbo].[Department]
END
GO
CREATE TABLE [dbo].[Department](
[DepartmentUUID] [uniqueidentifier] NOT NULL,
[TheVersionProperty] [timestamp] NOT NULL,
[DepartmentName] [nvarchar](80) NULL,
[CreateDate] [datetime] NOT NULL
)
ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID])
GO
ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName])
GO
CREATE TABLE [dbo].[Employee] (
/* [EmployeeUUID] [uniqueidentifier] NOT NULL, */
[EmployeeSurrogateKey] int not null IDENTITY(101,2),
[EmployeeTablePartitionOrdinal] int not null,
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
/*[TheVersionProperty] [timestamp] NOT NULL,*/
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeSurrogateKey,EmployeeTablePartitionOrdinal)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_Employee_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[Employee]
ADD CONSTRAINT [CK_Employee_PK_IsOdd] CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
/*
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [CK_Employee_PK_IsOdd]
CHECK ( ( [EmployeeSurrogateKey] % 2 ) != 0)
GO
*/
ALTER TABLE [dbo].[Employee] WITH CHECK ADD CONSTRAINT [CK_EmployeeTablePartitionOrdinal_Is_One]
CHECK ( [EmployeeTablePartitionOrdinal] = 1 )
GO
CREATE TABLE [dbo].[EmployeeDeprecated] (
/*[EmployeeDeprecatedUUID] [uniqueidentifier] NOT NULL,*/
[EmployeeDeprecatedSurrogateKey] int not null IDENTITY(102,2),
[EmployeeTablePartitionOrdinal] int not null,
[ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
/*[TheVersionProperty] [timestamp] NOT NULL,*/ /* Partitioned view 'ViewUpdateableDB.dbo.vwEmployeeAll' is not updatable because table '[ViewUpdateableDB].[dbo].[Employee]' has a timestamp column. */
[SSN] [nvarchar](11) NOT NULL,
[LastName] [varchar](64) NOT NULL,
[FirstName] [varchar](64) NOT NULL,
[CreateDate] [datetime] NOT NULL,
[UpdateDate] [datetime] NOT NULL,
[HireDate] [datetime] NOT NULL
)
GO
ALTER TABLE dbo.[EmployeeDeprecated] ADD CONSTRAINT PK_EmployeeDeprecated PRIMARY KEY NONCLUSTERED (EmployeeDeprecatedSurrogateKey,EmployeeTablePartitionOrdinal)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT CK_EmployeeDeprecated_SSN_Unique UNIQUE (SSN)
GO
ALTER TABLE [dbo].[EmployeeDeprecated] ADD CONSTRAINT FK_EmployeeDeprecatedToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID)
GO
/*
ALTER TABLE [dbo].[EmployeeDeprecated]
ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven] CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
/*
ALTER TABLE [dbo].[EmployeeDeprecated] WITH CHECK ADD CONSTRAINT [CK_EmployeeDeprecated_PK_IsEven]
CHECK ( ( [EmployeeDeprecatedSurrogateKey] % 2 ) = 0)
GO
*/
ALTER TABLE [dbo].[EmployeeDeprecated] WITH CHECK ADD CONSTRAINT [CK_EmployeeTablePartitionOrdinal_Is_Two]
CHECK ( [EmployeeTablePartitionOrdinal] = 2 )
GO
CREATE VIEW dbo.vwEmployeeAll AS
Select
EmployeeSurrogateKey,EmployeeTablePartitionOrdinal,ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.Employee
UNION ALL
Select
EmployeeSurrogateKey =
EmployeeDeprecatedSurrogateKey,EmployeeTablePartitionOrdinal,ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate
from dbo.EmployeeDeprecated
GO
declare @DepartmentUUID001 uniqueidentifier
select @DepartmentUUID001 = 'DDDDDDDD-0000-0000-0000-000000000101'
declare @DepartmentUUID002 uniqueidentifier
select @DepartmentUUID002 = 'DDDDDDDD-0000-0000-0000-000000000102'
INSERT INTO dbo.Department (DepartmentUUID , DepartmentName , CreateDate )
Select @DepartmentUUID001 , 'Department One' , CURRENT_TIMESTAMP
UNION
Select @DepartmentUUID002 , 'Department Two' , CURRENT_TIMESTAMP
/*
declare @EmployeeUUID001 uniqueidentifier
select @EmployeeUUID001 = 'EEEEEEEE-0000-0000-0000-000000001001'
declare @EmployeeUUID00A uniqueidentifier
select @EmployeeUUID00A = 'EEEEEEEE-0000-0000-AAAA-000000009001'
*/
INSERT INTO dbo.Employee (/*EmployeeUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate,EmployeeTablePartitionOrdinal)
Select /*@EmployeeUUID001 ,*/ @DepartmentUUID001 , '111-11-1111' , 'Smith', 'John' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '01/01/2001' , 1
INSERT INTO dbo.EmployeeDeprecated(/*EmployeeDeprecatedUUID,*/ParentDepartmentUUID,SSN,LastName,FirstName,CreateDate,UpdateDate,HireDate,EmployeeTablePartitionOrdinal)
Select /*@EmployeeUUID00A ,*/ @DepartmentUUID002 , '888-88-8888' , 'Jones', 'Mary' , CURRENT_TIMESTAMP , CURRENT_TIMESTAMP , '02/02/2002' , 2
GO
Select * from dbo.vwEmployeeAll
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP
Update dbo.vwEmployeeAll Set LastName = 'Henderson' where EmployeeSurrogateKey = 1
Update dbo.vwEmployeeAll Set UpdateDate = CURRENT_TIMESTAMP where EmployeeSurrogateKey = 2