本文介绍了为什么我的视图列可以为空?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Windows上运行的是PostgreSQL 9.2。

我有一个现有的表,其中包含一些不可为空的列:

CREATE TABLE testtable
(
  bkid serial NOT NULL,
  bklabel character varying(128),
  lacid integer NOT NULL
}

I Create a view on this table:

CREATE OR REPLACE VIEW test AS
SELECT testtable.bkid, testtable.lacid
from public.testtable;

我很惊讶,对于选定的列,视图Reports的INFORMATION_SCHEMA_COLUMNS是否可以为空?

select * from information_schema.columns where table_name = 'test'

报告:

"MyDatabase";"public";"test";"bkid";1;"";"YES";"integer";;;32;2;0;;"";;"";"";"";"";"";"";"";"";"";"MyDatabase";"pg_catalog";"int4";"";"";"";;"1";"NO";"NO";"";"";"";"";"";"";"NEVER";"";"NO"
"MyDatabase";"public";"test";"lacid";2;"";"YES";"integer";;;32;2;0;;"";;"";"";"";"";"";"";"";"";"";"MyDatabase";"pg_catalog";"int4";"";"";"";;"2";"NO";"NO";"";"";"";"";"";"";"NEVER";"";"NO"

这是预期行为吗?

我的问题是,我正在尝试在实体框架数据模型中导入此类视图,但失败了,因为所有列都标记为可为空。

编辑1

以下查询:

select attrelid, attname, attnotnull, pg_class.relname
from pg_attribute
inner join pg_class on attrelid = oid
where relname = 'test'

退货:

attrelid;attname;attnotnull;relname
271543;"bkid";f;"test"
271543;"lacid";f;"test"

不出所料,attnot空为""False""。

按照@Mike-Sherrill-Catcall的建议,我可以手动将它们设置为True:

update pg_attribute
set attnotnull = 't'
where attrelid = 271543

并且更改反映在INFORMATION_SCHEMA列中:

select * from information_schema.columns where table_name = 'test'

输出为:

"MyDatabase";"public";"test";"bkid";1;"";"NO";"integer";;;32;2;0;;"";;"";"";"";"";"";"";"";"";"";"MyDatabase";"pg_catalog";"int4";"";"";"";;"1";"NO";"NO";"";"";"";"";"";"";"NEVER";"";"NO"
"MyDatabase";"public";"test";"lacid";2;"";"NO";"integer";;;32;2;0;;"";;"";"";"";"";"";"";"";"";"";"MyDatabase";"pg_catalog";"int4";"";"";"";;"2";"NO";"NO";"";"";"";"";"";"";"NEVER";"";"NO"

我将尝试导入实体框架数据模型中的视图。

编辑2

正如猜测的那样,它起作用了,视图现在正确地导入到实体框架数据模型中。当然,如上所述,我不会将所有列都设置为不可为空,仅将基础表中的那些不可为空的列设置为不可为空。

推荐答案

我认为这是预期行为,但我不会假装完全理解它。基表中的列似乎具有正确的属性。

在此INFORMATION_SCHEMA底层的系统表中的列似乎是"attrnot空"。我在pgsql-hacker listserv:cataloguing NOT NULL constraints上只看到一个引用"attnotull"的线程。(但在早期版本中,该列可能有不同的名称。可能值得研究一下。)

您可以看到该查询的行为。您需要使用WHERE子句来准确地获取您需要查看的内容。

select attrelid, attname, attnotnull, pg_class.relname
from pg_attribute
inner join pg_class on attrelid = oid
where attname like 'something%'

在我的系统上,具有主键约束的列和具有NOT NULL约束的列将"attnotnull"设置为"t"。视图中的相同列将"attnotull"设置为"f"。

如果你适当地斜视头部和斜视,那种是有意义的。视图中的列未声明为NOT NULL。仅基表中的列。

列pg_属性.attnot空是可更新的。您可以将其设置为TRUE,该更改似乎反映在INFORMATION_SCHEMA视图中。虽然您可以直接将其设置为TRUE,但我认为将其设置为与基表中的值匹配会更方便。(更舒服,我的意思并不是说我完全不喜欢在系统表上胡闹。)

这篇关于为什么我的视图列可以为空?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-03 12:16