1

我有一个 postgresql 函数/存储过程,它执行以下操作: 1. 调用另一个函数并将值保存到变量中。2. 使用我从第一步获得的值作为参数执行另一个 sql 语句。

我的问题是查询没有返回任何数据。也不返回任何错误。我只是 postgresql 的新手,所以我不知道调试的最佳方法......但我在第 1 步之后添加了一个 RAISE NOTICE 命令,如下所示:

SELECT INTO active_id get_widget_id(widget_desc);
RAISE NOTICE 'Active ID is:(%)', active_id;

在 pgadmin3 屏幕的“消息”部分,我看到带有数据的调试消息:

注意:活动 ID 是:(2)

我想知道括号是否对我造成了问题。
这是我在第 2 步中尝试运行的 sql:

        SELECT d.id, d.contact_id, d.priority, cp.contact
        FROM widget_details d, contact_profile cp, contact_type ct
        WHERE d.rule_id=active_id
        AND d.active_yn = 't'
        AND cp.id=d.contact_id
        AND cp.contact_type_id=ct.id
        AND ct.name = 'email'
        Order by d.priority ASC

您会注意到,在我的 where 子句中,我引用了变量“active_id”。我知道这个查询应该至少返回一行,因为当我运行一个直接的 sql 选择(而不是使用这个函数)并将值 2 替换为变量“active_id”时,我得到了我正在寻找的数据。

任何建议将不胜感激。

谢谢。

编辑1:

这是完整的函数定义:

CREATE TYPE custom_return_type AS (
    widgetnum integer,
    contactid integer,
    priority integer,
    contactdetails character varying
);

CREATE OR REPLACE FUNCTION test(widget_desc integer)
  RETURNS SETOF custom_return_type AS
$BODY$
DECLARE 
     active_id integer; 
     rec custom_return_type ;

BEGIN
SELECT INTO active_id get_widget_id(widget_desc);
    RAISE NOTICE 'Active ID is:(%)', active_id;

FOR rec IN 
    SELECT d.id, d.contact_id, d.priority, cp.contact
        FROM widget_details d, contact_profile cp, contact_type ct
        WHERE d.rule_id=active_id
        AND d.active_yn = 't'
        AND cp.id=d.contact_id
        AND cp.contact_type_id=ct.id
        AND ct.name = 'email'
        Order by d.priority ASC
    LOOP
     RETURN NEXT rec;
END LOOP;   

 END
 $BODY$
4

2 回答 2

1

这是太复杂的几个级别(编辑:事实证明,Erwin 上次您发布相同内容时已经向您解释过)。首先使用RETURNS TABLEand RETURN QUERY

CREATE OR REPLACE FUNCTION test(fmfm_number integer)
RETURNS TABLE ( 
    widgetnum integer,
    contactid integer,
    priority integer,
    contactdetails character varying
) AS
$BODY$
BEGIN
    RETURN QUERY SELECT d.id, d.contact_id, d.priority, cp.contact
        FROM widget_details d, contact_profile cp, contact_type ct
        WHERE d.rule_id = get_widget_id(widget_desc)
        AND d.active_yn = 't'
        AND cp.id=d.contact_id
        AND cp.contact_type_id=ct.id
        AND ct.name = 'email'
        Order by d.priority ASC;
 END
 $BODY$ LANGUAGE plpgsql;

在这一点上,它可能很简单,可以变成一个微不足道的SQL函数甚至是一个视图。很难确定,因为这个函数在编写时没有多大意义:

  • 您永远不会在任何地方使用该参数fmfm_number;和
  • widget_desc从未定义

所以这个函数永远无法运行。显然,您没有向我们展示真正的源代码,而是某种与您真正遇到问题的代码不匹配的“简化”代码。

于 2013-07-09T03:13:49.927 回答
0

之间有区别:
SELECT INTO ...
[http://www.postgresql.org/docs/current/interactive/sql-selectinto.html]

SELECT select_expressions INTO [STRICT] target FROM ...;
[http://www.postgresql.org/docs/current/interactive/plpgsql-statements.html#PLPGSQL-STATEMENTS-SQL-ONEROW]

我想你想要:
SELECT get_widget_id(widget_desc) INTO active_id;

于 2013-07-08T18:51:40.980 回答