postgresql 将数据类型从varchar更改为cidr和macaddr

idfiyjo8  于 2023-02-15  发布在  PostgreSQL
关注(0)|答案(1)|浏览(213)

我有一个Postgres数据库,表已经创建好了,数据也已经导入到表中,我想把ipv4、ipv6、mac这几个列的数据类型从varchar改为cidr和macaddr,但是出现了错误(这两个列有时候没有值(NULL))。
错误:类型cidr的输入语法无效:""
这是我的table。

CREATE TABLE "network" (
id int4 NOT NULL,
ipv4 cidr NULL,
ipv6 varchar NULL,  -> ERROR: invalid input syntax for type cidr: ""
"oldIpv4" varchar NULL,
"oldIpv6" varchar NULL,
mac varchar NULL
)

为什么我不能改变数据类型?
更新:我想将ipv6,"oldIpv4","oldIpv6"的数据类型更改为cidr,但是这些列已经有""作为值。当它们有""作为值时,是否可以将它们的数据类型更改为cidr。或者我应该保留varchar?

kh212irz

kh212irz1#

因为:

select ''::cidr; 
ERROR:  invalid input syntax for type cidr: "".

空字符串不是有效值.要处理的方法是:

select nullif('', '')::cidr; 
NULL

select pg_typeof(nullif('', '')::cidr);
 pg_typeof 
-----------
 cidr

将空字符串更改为NULLcidr值。

    • 更新**

要使用一个字段("oldIpv4")更新另一个字段(ipv4)的值:

create table cidr_test(id integer, ipv4 cidr, "oldIpv4" varchar);
insert into cidr_test values 
    (1, null, '192.168.100.128/25'), 
    (2, null, '10.1.2.3/32'), 
    (3, null, '');

select * from cidr_test ;
 id | ipv4 |      oldIpv4       
----+------+--------------------
  1 | NULL | 192.168.100.128/25
  2 | NULL | 10.1.2.3/32
  3 | NULL | 

begin ;
update cidr_test set ipv4 = nullif("oldIpv4", '')::cidr;

select * from cidr_test ;
 id |        ipv4        |      oldIpv4       
----+--------------------+--------------------
  1 | 192.168.100.128/25 | 192.168.100.128/25
  2 | 10.1.2.3/32        | 10.1.2.3/32
  3 | NULL               | 

commit;
    • 更新#2**

就地更改柱类型:

truncate cidr_test ;

 \d cidr_test 
                   Table "public.cidr_test"
 Column  |       Type        | Collation | Nullable | Default 
---------+-------------------+-----------+----------+---------
 id      | integer           |           |          | 
 ipv4    | cidr              |           |          | 
 oldIpv4 | character varying |           |          | 

insert into cidr_test values 
    (1, null, '192.168.100.128/25'), 
    (2, null, '10.1.2.3/32'), 
    (3, null, '');

ALTER TABLE
    cidr_test 
ALTER COLUMN 
    "oldIpv4" TYPE cidr USING nullif("oldIpv4", '')::cidr;

\d cidr_test 
              Table "public.cidr_test"
 Column  |  Type   | Collation | Nullable | Default 
---------+---------+-----------+----------+---------
 id      | integer |           |          | 
 ipv4    | cidr    |           |          | 
 oldIpv4 | cidr    |           |          | 

select * from cidr_test ;
 id | ipv4 |      oldIpv4       
----+------+--------------------
  1 | NULL | 192.168.100.128/25
  2 | NULL | 10.1.2.3/32
  3 | NULL | NULL

相关问题