postgresql - 有没有一种简单的方法可以用默认值替换 null ?
问题描述
我想将数据从一个表复制到另一个表中,但源表可能在目标表不允许空值但具有默认值的列中有空值:
drop table if exists table_with_nulls;
create table table_with_nulls
(
value1 integer,
value2 integer
);
insert into table_with_nulls values (1, null);
drop table if exists table_with_defaults;
create table table_with_defaults
(
value1 integer not null default 10,
value2 integer not null default 20
);
insert into table_with_defaults (value1, value2)
select value1, value2 from table_with_nulls;
由于 table_with_nulls.value2 中的空值,这会引发异常。是否有一种相当简单的方法可以为 table_with_defaults.value2 获得 20 的值?
解决方案
示例表:
create table table_with_defaults
(
value1 integer not null default 10,
value2 numeric not null default 0.0,
value3 text not null default '-- nothing --',
value4 date not null default current_date,
value5 text
);
您可以查询系统目录pg_attribute和pg_attrdef以查找表列的默认表达式:
select attname, adsrc
from pg_attribute a
left join pg_attrdef d on adrelid = attrelid and adnum = attnum
where attnum > 0
and attrelid = 'table_with_defaults'::regclass;
attname | adsrc
---------+-----------------------
value1 | 10
value2 | 0.0
value3 | '-- nothing --'::text
value4 | ('now'::text)::date
value5 |
(5 rows)
在 plpgsql 函数中使用查询来构建和执行适当的语句:
create or replace function copy_table_with_defaults(table_from regclass, table_to regclass)
returns void language plpgsql as $$
declare
column_list text;
begin
select string_agg(
case when adsrc is null then attname
else format('coalesce(%I, %s)', attname, adsrc)
end, ',')
from pg_attribute a
left join pg_attrdef d on adrelid = attrelid and adnum = attnum
where attnum > 0
and attrelid = table_to
into column_list;
execute format($ex$
insert into %I
select %s
from %I
$ex$, table_to, column_list, table_from);
end $$;
使用功能:
select copy_table_with_defaults('table_with_nulls'::regclass, 'table_with_defaults'::regclass);
推荐阅读
- angular - ngrx 订阅的商店不会在状态更改 Angular5 时更新
- java - Java - 用 AM/PM 解析日期,紧挨秒(没有空格)
- symfony - Docker with Symfony 4 - Unable to see the file changes
- spring-boot - 无法从命令行工具连接到 spring boot websocket 示例
- r - 将函数应用于 R 中的嵌套 tibble 数据结构
- node.js - npm optimist 不要传递一些参数,Windows
- c++ - (几个 qdockWidget) QWidget::repaint: Recursive repaint detected kernel\qwidget.cpp: 5557
- angularjs - 在 Auth0 中授权后访问令牌
- jquery - jQuery Multiple Select - 使用“ALL”选择/取消选择项目
- powershell - 使用 powershell 在 IIS 中设置变量