您如何在 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;
$$;
我正在编写一个存储过程,我需要在循环访问一组值时定义一个临时行,然后在随后的更新语句中引用该临时行的属性。这是我的存储过程:
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;
$$;