您如何在 Postgresql 11 的存储过程的另一部分中使用别名和引用该别名?

How do you alias and reference that alias in another part of a stored procedure in Postgresql 11?

我正在编写一个存储过程,我需要在循环访问一组值时定义一个临时行,然后在随后的更新语句中引用该临时行的属性。这是我的存储过程:

create or replace procedure updateReputation(sentID int)
as $$ 
declare temprow peoplereviews%rowtype;
declare grade double precision = getRuleGrade(sentID);
  begin
    for temprow in select pr.reviewerid as rid, pr.rulereviewid as rri, pr.rulereview as rr, r.reputation as r
                   from peoplereviews pr inner join sentencerules sr on pr.sentenceid = sr.sentenceid
                   inner join reviewers r on pr.reviewerid = r.reviewerid
                   where pr.sentenceid = sentID
                   and sr.taggedruleid = pr.rulereviewid
    loop
      if (grade > .5) then
        if (temprow.rr = 1) then
          update reviewers
          set reputation = temprow.r + 10
          where reviewerid = temprow.rid;
        else
          update reviewers
          set reputation = temprow.r - 10
          where reviewerid = temprow.rid;
        end if;
      else
        if (temprow.rr = 0) then
          update reviewers
          set reputation = temprow.r + 10
          where reviewerid = temprow.rid;
        else
          update reviewers
          set reputation = temprow.r - 10
          where reviewerid = temprow.rid;
        end if;
    end if;
  end loop;
  end;
$$ language plpgsql;

当我调用它时出现错误:

ERROR:  record "temprow" has no field "rr"
CONTEXT:  SQL statement "SELECT (temprow.rr = 1)"
PL/pgSQL function updatereputation(integer) line 12 at IF
SQL state: 42703

我也尝试过不使用别名并将其写成 temprow.pr.rulereview,但得到了这个错误:

missing FROM-clause entry for table "pr"
LINE 1: SELECT (temprow.pr.rulereview = 1)
                ^
QUERY:  SELECT (temprow.pr.rulereview = 1)
CONTEXT:  PL/pgSQL function updatereputation(integer) line 12 at IF
SQL state: 42P01

所以我想知道在这种情况下是否可以使用别名,如果不能,最好的方法是引用临时行的属性。

通过声明的行类型的属性回避问题,您不需要任何复杂的 PL/PGSQL 代码。您可以使用带有 FROM 列表的单个 SQL UPDATE command 加入反对:

CREATE OR REPLACE PROCEDURE updateReputation(sentID int)
LANGUAGE sql
AS $$
  UPDATE reviewers r
  SET reputation = reputation + (CASE WHEN 
      pr.rulereview = (getRuleGrade(sentID) > .5)::int
    THEN
      +10
    ELSE
      -10
    END)
  FROM peoplereviews pr
  INNER JOIN sentencerules sr ON (pr.sentenceid = sr.sentenceid
                                  AND pr.rulereviewid = sr.taggedruleid)
  WHERE pr.reviewerid = r.reviewerid -- this is the join
    AND pr.sentenceid = sentID;
$$;