【问题标题】:How to return a new value in a trigger from a cte in PostgreSQL如何从 PostgreSQL 中的 cte 在触发器中返回新值
【发布时间】:2015-09-21 16:47:38
【问题描述】:

根据我在 PostgreSQL (9.3) 中的上一个问题How to check a sequence efficiently for used and unused values in PostgreSQL,我现在有一个表格 chart_gap,其中列出了表格图表中所有未使用的图表编号:

CREATE TABLE chart_gap (chart_number integer);

为了更多地了解触发器,我添加了以下触发器过程,或多或少取自该问题:

CREATE OR REPLACE FUNCTION next_chart() RETURNS trigger AS $BODY$
BEGIN
  -- Check for empty chart number
  IF NEW.chart_number IS NULL THEN

    WITH ins AS (
      SELECT chart_number
      FROM   chart_gap
      WHERE  pg_try_advisory_xact_lock(chart_number)
      LIMIT  1
    )
    DELETE FROM chart_gap c
    USING  ins i
    WHERE  i.chart_number = c.chart_number;

    NEW.chart_number := select chart_number from ins;   <--WRONG!       
  END IF;

  RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql VOLATILE;

触发过程与图表文件相关联:

CREATE TRIGGER next_chart
  BEFORE INSERT
  ON charts
  FOR EACH ROW
  EXECUTE PROCEDURE next_chart();

我尝试做的是在添加新图表记录时替换图表中的空图表编号字段。这可以在触发器中完成吗? (还有什么 是正确的语法吗??)

【问题讨论】:

  • 它没有按照您想要的方式工作吗?您是否收到语法错误? CTE 与您想要实现的目标有什么关系?

标签: database postgresql


【解决方案1】:

plpgsql 函数中,您可以使用query RETURNING ... INTO ...,如下所示:

CREATE FUNCTION next_chart() RETURNS trigger AS $BODY$
BEGIN
  -- Check for empty chart number
  IF NEW.chart_number IS NULL THEN
    WITH ins AS (
      SELECT chart_number
      FROM   chart_gap
      WHERE  pg_try_advisory_xact_lock(chart_number)
      LIMIT  1
    )
    DELETE FROM chart_gap c
    USING  ins i
    WHERE  i.chart_number = c.chart_number
    RETURNING i.chart_number INTO NEW.chart_number;
  END IF;

  RETURN NEW;
END;
$BODY$ LANGUAGE plpgsql VOLATILE;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多