【问题标题】:How to declare variable having the type of a user-defined domain with a non-null check constraint如何声明具有非空检查约束的用户定义域类型的变量
【发布时间】:2018-12-06 00:57:50
【问题描述】:

我定义了一个派生自复合类型的域,该复合类型具有 CHECK 约束以防止其组件值之一为空。我想编写一个具有这种类型变量的 plpgsql 语言函数。我没有声明这样一个变量。

这是一个简化的场景示例,它给了我相同的错误消息:

CREATE DOMAIN myint AS integer
  CONSTRAINT not_null CHECK (VALUE IS NOT NULL);

CREATE FUNCTION myfunc() RETURNS myint LANGUAGE plpgsql AS $$
  DECLARE
    notnullint myint;
  BEGIN
    notnullint := 1;
    RETURN notnullint;
  END
$$;

mydb=# select myfunc();
ERROR:  value for domain myint violates check constraint "not_null"
CONTEXT:  PL/pgSQL function myfunc() line 4 during statement 
block local variable initialization

我是否困惑于认为不可能将 plpgsql 变量绑定到具有非空约束的域类型的值?我很难相信 PostgreSQL 会有这样的限制。

注意:在我的实际应用程序中,我想为变量分配 INSERT 语句的返回值,因此在 DECLARE 块中分配值似乎不合适。

【问题讨论】:

  • 请注意——也许在 PostgreSQL 12 中,对于没有约束子句的域类型会有一些优化。当使用域时,就像类型别名一样。现在看起来更实用的是,在没有必要时不使用约束。

标签: postgresql plpgsql


【解决方案1】:

您可以在DECLARE 部分初始化变量:

CREATE FUNCTION myfunc() RETURNS myint LANGUAGE plpgsql AS $$
  DECLARE
    notnullint myint = 0;
  BEGIN
    notnullint := 1;
    RETURN notnullint;
  END
$$;

注意:在我的实际应用程序中,我想为变量分配 INSERT 语句的返回值,因此在 DECLARE 块中分配值似乎不合适。

我不明白这个逻辑。在这种情况下,必须初始化变量,而您别无选择。当然,你可以在函数体中给它赋值。

【讨论】:

  • 我明白了。我来自变量不可变的功能背景,所以我什至没有想到设置它然后重置它。谢谢!
  • 确实,这可能有点令人困惑,因为初始化类似于其他语言中的常量声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-09
  • 1970-01-01
  • 2012-09-28
  • 1970-01-01
相关资源
最近更新 更多