加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

SQLServer 表字段为 NULL 而视图为NOT NULL 问题

发布时间:2020-12-12 13:12:35 所属栏目:MsSql教程 来源:网络整理
导读:之前有处理几次这个问题,不过还是简单记录下来吧。 -- 创建测试表和视图-- DROP DATABASE Demo;CREATE DATABASE Demo;GOUSE DemoGO-- DROP TABLE [dbo].[TestTable]CREATE TABLE [dbo].[TestTable]([Identifier] [uniqueidentifier] NOT NULL,[Name] [varch

之前有处理几次这个问题,不过还是简单记录下来吧。


--  创建测试表和视图

--  DROP DATABASE Demo;
CREATE DATABASE Demo;
GO
USE Demo
GO

--  DROP TABLE [dbo].[TestTable]
CREATE TABLE [dbo].[TestTable](
	[Identifier] [uniqueidentifier] NOT NULL,[Name] [varchar](50) NULL,[value] [numeric](18,4) NULL
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[TestTable] 
ADD CONSTRAINT [PK_TestTable] PRIMARY KEY CLUSTERED([Identifier])
GO

ALTER TABLE [dbo].[TestTable] 
ADD CONSTRAINT [DF_TestTable_Identifier] DEFAULT (newsequentialid()) FOR [Identifier]
GO


--  DROP VIEW [dbo].[VTestTable] 
CREATE VIEW [dbo].[VTestTable]    
AS    
SELECT [Identifier],[Name],[value]
FROM dbo.TestTable
GO




插入数据到视图(正常):

INSERT INTO [VTestTable]([Identifier],[value])
SELECT NEWID(),'KK',NULL
GO

UPDATE [VTestTable] SET [value]=NULL
GO


由于字段[value]没有默认值,读取或插入数据时null改为0 :

--  由于字段[value]没有默认值,读取或插入数据时null改为0
ALTER VIEW [dbo].[VTestTable]    
AS    
SELECT [Identifier],ISNULL([value],0) [value]
FROM dbo.TestTable
GO

此时看到,视图中的字段 [value] 为 not null :



此时对视图更新或插入失败:

--  此时对视图更新或插入失败
INSERT INTO [VTestTable]([Identifier],NULL
GO

UPDATE [VTestTable] SET [value]=NULL
GO

消息 4406,级别 16,状态 1,第 1 行
对视图或函数 'VTestTable' 的更新或插入失败,因其包含派生域或常量域。


原因是:视图不允许为NULL!


解决方法(一):

--  解决方法(一):增加触发器
--  DROP TRIGGER [dbo].[tr_VTestTable_insert]
CREATE TRIGGER [dbo].[tr_VTestTable_insert]
ON DBO.[VTestTable]
INSTEAD OF INSERT
AS 
BEGIN
    INSERT INTO TestTable([Name],[value])
    SELECT [Name],0) FROM inserted;
END
GO

--  DROP TRIGGER [dbo].[tr_VTestTable_update]
CREATE TRIGGER [dbo].[tr_VTestTable_update]
ON DBO.[VTestTable]
INSTEAD OF UPDATE
AS
BEGIN
    UPDATE t1 SET 
    t1.[Name] = t2.[Name],t1.[value] = ISNULL(t2.[value],0)
    FROM TestTable AS t1,inserted AS t2 WHERE t1.[Identifier] = t2.[Identifier]
END
GO

--  此时操作正常!
INSERT INTO [VTestTable]([Identifier],NULL
GO
UPDATE [VTestTable] SET [value]=NULL --更新为null,触发器替换为0
GO

解决方法(二):

--  解决方法(二):增加默认值约束

/*--删除刚创建的对象
DROP TRIGGER [dbo].[tr_VTestTable_insert]
DROP TRIGGER [dbo].[tr_VTestTable_update]
*/

--  增加默认值约束
ALTER TABLE [dbo].[TestTable] 
ADD CONSTRAINT [DF_TestTable_value] DEFAULT (0) FOR [value]
GO

--  更新表中原有为 NULL 的值
UPDATE [dbo].[TestTable] SET [value] = 0
GO

--修改视图
ALTER VIEW [dbo].[VTestTable]    
AS    
SELECT [Identifier],[value]
FROM dbo.TestTable
GO


--  插入时不显示插入,[value] 默认为0;
INSERT INTO [VTestTable]([Identifier],[Name])
SELECT NEWID(),'KK'
GO

--  此时允许更新为 NULL !
UPDATE [VTestTable] SET [value]=NULL
GO

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读