视图中定义的默认值不会生效,因视图不存储数据、不支持DEFAULT约束,仅基表列定义中的DEFAULT配合INSERT时省略该列才能触发自动填充。

视图里定义的默认值根本不会被数据库执行——因为视图不存数据,也不参与INSERT时的列值生成逻辑。
视图本身没有DEFAULT语法支持
SQL标准中,CREATE VIEW语句不允许出现DEFAULT、NOT NULL、CHECK等约束定义。你如果在视图定义里写类似SELECT id, name, COALESCE(status, 'active') AS status FROM users,这只是表达式计算,不是“给status列设默认值”。数据库不会把COALESCE结果当作插入基表时的兜底值。
常见误操作:
- 在视图里用
ISNULL()或COALESCE()包装字段,以为能影响INSERT行为 - 给视图字段起别名后,在应用层漏传原基表必填列,还指望视图“补上默认值”
- 在Access或某些ORM里勾选了“使用视图默认值”,但底层数据库(如SQL Server)压根不认这个配置
真正起作用的默认值只存在于基表结构中
只有基表(例如users)的列定义里有DEFAULT GETDATE()或DEFAULT 'pending',且INSERT语句**没显式提供该列的值**,数据库才会自动填充。
关键限制条件:
- INSERT必须省略该列:比如
INSERT INTO users (id, name) VALUES (1, 'Alice'),此时status列才能触发默认值 - 不能显式传
NULL:像INSERT INTO users (id, name, status) VALUES (1, 'Alice', NULL),哪怕status有DEFAULT,也会写入NULL(尤其在SQL Server严格模式下) - 视图INSERT时,所有列都得显式列出:比如
INSERT INTO active_users (id, name) VALUES (1, 'Alice'),数据库会把它翻译成对users表的INSERT,但仅限于视图暴露的列;如果users.status是NOT NULL且无DEFAULT,而视图又没包含status列,就会报错Column 'status' doesn't have a default value
为什么有些工具显示“默认值已生效”,实际却没写进基表?
这通常是客户端或中间层(如Access表单、低代码平台)在UI层做了模拟,默认值只存在前端内存里,提交时没传给SQL引擎。
排查步骤:
- 抓取真实发往数据库的INSERT语句(用SQL Server Profiler / pg_stat_statements / MySQL general_log)
- 确认语句中是否包含那个“应该被默认填充”的列;如果出现了,值是什么(
NULL?空字符串?还是根本没这个字段?) - 检查基表定义:
SELECT COLUMN_NAME, IS_NULLABLE, COLUMN_DEFAULT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'users'(SQL Server)或\d users(PostgreSQL)
最常被忽略的一点:视图只是查询的封装,它既不接管约束,也不拦截或改写DML语义。所谓“默认值传递”,本质是基表结构 + INSERT语句写法 + 数据库模式(如SQL Server的ANSI_NULLS设置)三者共同作用的结果,和视图无关。

















