插入后,如何以编程方式将空值转换为列的默认值?

时间:2013-01-08 10:48:05

标签: postgresql

我有一张表,我为其中的一些列提供了默认值。我想创建一个函数,其参数对应于在将任何空值修改为列的默认值后将在表中插入记录的列。我不希望以编程方式构造基于哪些参数为null的查询。基本上我想要像

这样的东西
INSERT into Table (c1, c2, c3, c4)
Values (coalesce(somevar, DEFAULT(c1)), ...)

这可能吗?我见过mysql can do this。 postgres提供类似的东西吗? 我使用的是9.1版

更新:此question提供了一些有趣的解决方案,但不幸的是结果始终是文本。我想将默认值作为其真正的数据类型,以便我可以使用它来插入它。我试图找到一个解决方案,将默认值从文本转换为其数据类型(以文本形式提供),但我找不到方法:

SELECT column_name, column_default, data_type
FROM information_schema.columns
WHERE (table_schema, table_name) = ('public', 'mytable')
AND column_name = 'mycolumn'
ORDER BY ordinal_position;

上面将column_default和data_type作为文本返回,那么如何将column_default转换为data_type的?如果我能做到这一点,那我的问题就会解决。

2 个答案:

答案 0 :(得分:1)

如果表定义接受带有所有列的默认值的INSERT,则下面的两步法可能有效:

CREATE FUNCTION insert_func(c1 typename, c2 typename, ...)
RETURNS VOID AS $$
DECLARE
 r record;
BEGIN
 INSERT into the_table default values  returning *,ctid INTO r;
 UPDATE the_table set
  col1=coalesce(c1,r.col1),
  col2=coalesce(c2,r.col2),
  ...
 WHERE the_table.ctid=r.ctid;
END;
$$ language plpgsql;

诀窍是在插入时将所有默认值放入r记录变量,然后在UPDATE中使用它们来替换任何非默认值。 ctid是一个伪列,用于指定刚刚插入的行的内部唯一ID。

警告:如果某些列具有默认空值和非空检查(或任何暗示不接受默认值的检查),则此方法将不起作用,因为第一个INSERT会失败。

答案 1 :(得分:0)

我通过创建一个包含LIKEINCLUDING DEFAULTS子句的临时表来解决类似于Daniel的解决方案,以便匹配我的行类型,然后使用

INSERT INTO temp_table (c1, c2, ...) VALUES(x1, DEFAULT, ..)

对我感兴趣的任何列使用default关键字。然后我通过从临时选择并使用

插入到真实表中

VALUES( x1, coalesce(x2, temp_table.c2), ...)

我不喜欢它,但它可以正常工作:我可以选择哪个列我想要执行此操作“null-replace-with-default”检查,如果我重载我可以在一行中使用多行函数接受记录数组。