【问题标题】:Prepared Statement Does Not Exists, PostgreSQL准备好的语句不存在,PostgreSQL
【发布时间】:2022-12-31 20:40:23
【问题描述】:

我用这段代码创建了存储过程

CREATE PROCEDURE get_conferences_for_attendee
(
  IN start_time TIMESTAMP,
  IN end_time TIMESTAMP,
  IN email VARCHAR(255),
  IN deleted BOOLEAN
)
AS
$$
  SELECT c.localuuid, c.title, i.id, i.start_time, i.end_time, i.status, a.email, a.deleted
  FROM Conference c
  INNER JOIN Instance i ON i.conference_localuuid = c.localuuid
  INNER JOIN Conference_Attendees ca ON ca.conference_localuuid = c.localuuid
  INNER JOIN Attendee a ON ca.attendees_localuuid = a.localuuid
  WHERE i.start_time BETWEEN start_time AND end_time
  AND a.email = email
  AND a.deleted = deleted
$$ LANGUAGE SQL;

这回来了

创建程序

我可以看到我的程序

SELECT proname, prorettype
FROM pg_proc
WHERE pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = 'public');


           proname            | prorettype 
------------------------------+------------
 get_conferences_for_attendee |       2278

当我尝试执行时,出现标题错误。

EXECUTE get_conferences_for_attendee ('2022-12-26T00:00:00', '2023-01-01T23:59:59', 'yacs.demo2@abc.com', false);

错误:准备好的语句“get_conferences_for_attendee”不存在

更新

我找到了一个解决方案,但我不确定这是否是创建它的正确方法。对我来说看起来太复杂了。

CREATE TYPE conference_record AS (                                                                                     
  localuuid VARCHAR(255),
  title VARCHAR(255),
  id VARCHAR(255),
  start_time TIMESTAMP,
  end_time TIMESTAMP,
  status VARCHAR(255),
  email VARCHAR(255),
  deleted BOOLEAN
);

CREATE FUNCTION get_conferences_for_attendee
(
  IN start_time TIMESTAMP,
  IN end_time TIMESTAMP,
  IN email VARCHAR(255),
  IN deleted BOOLEAN
)
RETURNS SETOF conference_record AS $$
  BEGIN
    RETURN QUERY
    SELECT c.localuuid, c.title, i.id, i.start_time, i.end_time, i.status, a.email, a.deleted
    FROM Conference c
    INNER JOIN Instance i ON i.conference_localuuid = c.localuuid
    INNER JOIN Conference_Attendees ca ON ca.conference_localuuid = c.localuuid
    INNER JOIN Attendee a ON ca.attendees_localuuid = a.localuuid
    WHERE i.start_time BETWEEN $1 AND $2
    AND a.email = $3
    AND a.deleted = $4;
  END;
$$ LANGUAGE plpgsql;
SELECT * FROM get_conferences_for_attendee ('2022-12-26T00:00:00', '2023-01-01T23:59:59', 'yacs.demo1@abc.com', false);

【问题讨论】:

  • 准备好的语句与存储过程不同。您很可能需要声明 CALL 而不是 EXECUTE
  • 我不能用存储过程来做。我找到了一个解决方案,但我不确定这是创建存储选择语句的正确方法。你能检查一下吗?
  • 对于一个函数,您需要一个简单的 SELECT。忘了说那个

标签: postgresql


【解决方案1】:
  1. As pointed out in the comments,要使用程序,您需要CALL your_procedure();

  2. 您提供的代码看起来像是您试图从中获取某些东西,因此 function 更合适 - procedures 可以通过 outinout 参数或副作用返回数据,例如将它们转储到外面的桌子。

  3. 您稍后在编辑中添加的函数和类型定义看起来不错。如果您打算将其直接输入到表中,则无需定义自定义类型,而是指定 RETURNS SETOF your_target_table_nameRETURNS TABLE (LIKE your_target_table_name)

    您也可以将其设为 LANGUAGE sql - 因为您没有使用任何特定于 plpgsql 的东西,所以您不需要随之而来的额外开销。您只需删除BEGIN RETURN QUERYEND,只留下最基本的查询。

  4. 您也可以为此使用常规的prepared statement

    PREPARE get_conferences_for_attendee(
               TIMESTAMP,
               TIMESTAMP,
               VARCHAR(255),
               BOOLEAN                  ) AS
    SELECT 
        c.localuuid, 
        c.title, 
        i.id, 
        i.start_time, 
        i.end_time, 
        i.status, 
        a.email, 
        a.deleted
    FROM Conference c
    INNER JOIN Instance i               ON i.conference_localuuid = c.localuuid
    INNER JOIN Conference_Attendees ca  ON ca.conference_localuuid = c.localuuid
    INNER JOIN Attendee a               ON ca.attendees_localuuid = a.localuuid
    WHERE i.start_time BETWEEN $1 AND $2
    AND a.email = $3
    AND a.deleted = $4;
    

    并完全按照您最初计划的方式使用它,使用 EXECUTE

    EXECUTE get_conferences_for_attendee(
               '2022-12-26T00:00:00', 
               '2023-01-01T23:59:59', 
               'yacs.demo1@abc.com', 
               false);
    

    Online demo

【讨论】:

    猜你喜欢
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 2014-05-09
    • 1970-01-01
    • 2014-02-05
    • 2012-01-02
    相关资源
    最近更新 更多