Plpgsql Postgresql9-4-使用联接的用户定义函数-错误:缺少表的从句项
我第一次尝试使用pg/sql,我编写了这个函数,试图从使用联接的查询返回结果 当我自己在上面运行查询时,它会工作。但是,当它在我编写的函数中运行时,它会抱怨缺少一个。我还使用了表别名,希望它能解决这个问题,但事实并非如此 我从以下表格和行中获取信息Plpgsql Postgresql9-4-使用联接的用户定义函数-错误:缺少表的从句项,plpgsql,postgresql-9.3,Plpgsql,Postgresql 9.3,我第一次尝试使用pg/sql,我编写了这个函数,试图从使用联接的查询返回结果 当我自己在上面运行查询时,它会工作。但是,当它在我编写的函数中运行时,它会抱怨缺少一个。我还使用了表别名,希望它能解决这个问题,但事实并非如此 我从以下表格和行中获取信息 TABLE | ROW --------------------------------------- banned_users | banned_lcl_account -----
TABLE | ROW
---------------------------------------
banned_users | banned_lcl_account
---------------------------------------
rhost_active_users | active_users
下面是我运行函数时出现的错误
ERROR: missing FROM-clause entry for table "a_u"
LINE 1: SELECT LOOP_V.a_u.ipaddress
这是我写的函数
CREATE OR REPLACE FUNCTION GET_BANNED_ACTIVE_USERS()
RETURNS TABLE
(
SRC_HOST TEXT,
DST_HOST TEXT
)
AS $$
DECLARE
LOOP_V RECORD;
BEGIN
FOR LOOP_V IN (
select
b_u.banned_lcl_account,
a_u.ipaddress,
a_u.hostip,
date_trunc ('second', a_u.time_captured)
from banned_users as b_u
inner join rhost_active_users as a_u
on b_u.banned_lcl_account = a_u.active_users
and a_u.hostip <> 'TTY Login'
or a_u.hostip <> 'Local PTS Login'
)
LOOP
SRC_HOST := LOOP_V.a_u.ipaddress;
DST_HOST := LOOP_V.a_u.hostip;
END LOOP;
END; $$
LANGUAGE 'plpgsql';
--select CHECK_BANNED_ACCOUNTS()
你的问题是:
SRC_HOST := LOOP_V.a_u.ipaddress;
DST_HOST := LOOP_V.a_u.hostip;
用于循环变量的记录仅包含列名,而不包含其表别名。因此,该记录只有以下字段:ipaddress和hostip。因此,您眼前的问题可以通过以下方法解决:
SRC_HOST := LOOP_V.ipaddress;
DST_HOST := LOOP_V.hostip;
但是,整个功能过于复杂。您不需要循环,也不需要PL/pgSQL。这可以写成一个简单的SQL函数:
CREATE OR REPLACE FUNCTION GET_BANNED_ACTIVE_USERS()
RETURNS TABLE (SRC_HOST TEXT,DST_HOST TEXT)
AS $$
select a_u.ipaddress,
a_u.hostip,
from banned_users as b_u
join rhost_active_users as a_u
on b_u.banned_lcl_account = a_u.active_users
and (a_u.hostip <> 'TTY Login' or a_u.hostip <> 'Local PTS Login')
$$
LANGUAGE sql;
最后:
语言“plpgsql”
语言名称是一个标识符,请不要将其括在单引号中:
LANGUAGE plpgsql;
或
感谢您的帮助:所以,在决定何时使用函数以及以何种方式使用函数时,我似乎遇到了一个概念上的问题。你能推荐一本书,以一种将事情放在上下文中的方式来讨论pg/sql吗。到目前为止,我读到的所有材料都没有提供上下文,只是简单的例子。-这里有一个简单的规则,您应该尽量减少执行的SQL语句的数量-可以用一个可读的SQL做什么,您应该用一个SQL做什么。在循环内部使用SQL应该是最关键的—安全性、可读性、当前API。。。
LANGUAGE plpgsql;
LANGUAGE sql;