3

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

INSERT into Table (c1, c2, c3, c4)
Values (coalesce(somevar, DEFAULT(c1)), ...)

这可能吗?我已经看到mysql 可以做到这一点。postgres 是否提供类似的功能?我使用的是 9.1 版

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

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 的?如果我能做到这一点,那么我的问题就迎刃而解了。

4

2 回答 2

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 将失败。

于 2013-01-08T23:38:40.183 回答
0

我已经使用类似于 Daniel 的解决方案解决了我的问题,方法是创建一个带有LIKEINCLUDING DEFAULTS子句的临时表以匹配我的行类型,然后我使用

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

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

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

我不喜欢它,但它工作正常:我可以选择我想在哪些列上执行此“null-replace-with-default”检查,如果我重载我的函数以接受,它可以一次性处理多行一个记录数组。

于 2013-01-09T10:05:05.937 回答