我刚刚发现我可以将任何类型的值插入到类型为 PostgreSQL (9.6) 的列中text
:
drop table if exists d cascade;
create table d ( a text );
insert into d values ( 42 );
insert into d values ( true );
select a, pg_typeof( a ) from d;
a | pg_typeof
------+-----------
42 | text
true | text
(2 rows)
这是故意的功能吗?我做错了什么吗?有没有设置可以避免这种情况?这不违反 RDBMS 应该是类型安全的假设吗?
我知道这text
在 PostgreSQL 中就像一个包罗万象的东西,这通常很方便,因为你可以编写任意类型的字符串表示。但有时你肯定想确保只有字符串被插入到给定的列中,以排除隐式转换值。
我能做些什么来避免“随意”的类型转换吗?
是的,隐式类型转换是一个有意的功能。无论哪种方式都有利有弊,但这就是 postgres的工作方式:
不,一切仍然是类型安全的,并且“SQL 是一种强类型语言”。隐式转换不会改变这一点。
没有弄乱系统目录,这通常是一个非常糟糕的主意(在某些情况下是不可能的),你可以做很多事情来完全避免隐式转换。即使您在任何地方都包含显式转换,隐式转换仍然可能会错误地发生:
dbfiddle在这里
@Jack 说了什么。
另外,准确地说,你的演员
INSERT
阵容在常识上是“隐含的”:但这是一个赋值转换,而不是 Postgres 术语中的隐式转换。这是一个重要的区别,隐式转换有更多的应用。看:
赋值或隐式转换仅基于...
1.系统目录中的一个条目
pg_cast
与
castcontext = 'a'
或castcontext = 'i'
分别。当前安装的完整列表:
2. 附加通用规则
手册:
大胆强调我的。
pg_cast
从理论上讲,您可以通过更改'i'
或'a'
更改(“显式”)来混淆条目'e'
- 这可能会产生深远的影响并且是一个坏主意,除非您确切知道自己在做什么 - 但不能使用自动 I/O 转换强制转换。有关的:
演员表
unknown
再次引用有关“常量”的手册:
更多细节在该章节。
unknown
-type 字面量是字符串,可以使用上面提到的“自动 I/O 转换转换”进行转换。但是 Postgres 需要在确定合适的类型转换之前确定目标类型。在简单的赋值中,目标类型是显而易见的。在其他情况下,确定目标类型可能很棘手。在以下方面有大量规则: