Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Plpgsql Postgresql9-4-使用联接的用户定义函数-错误:缺少表的从句项_Plpgsql_Postgresql 9.3 - Fatal编程技术网

Plpgsql Postgresql9-4-使用联接的用户定义函数-错误:缺少表的从句项

Plpgsql Postgresql9-4-使用联接的用户定义函数-错误:缺少表的从句项,plpgsql,postgresql-9.3,Plpgsql,Postgresql 9.3,我第一次尝试使用pg/sql,我编写了这个函数,试图从使用联接的查询返回结果 当我自己在上面运行查询时,它会工作。但是,当它在我编写的函数中运行时,它会抱怨缺少一个。我还使用了表别名,希望它能解决这个问题,但事实并非如此 我从以下表格和行中获取信息 TABLE | ROW --------------------------------------- banned_users | banned_lcl_account -----

我第一次尝试使用pg/sql,我编写了这个函数,试图从使用联接的查询返回结果

当我自己在上面运行查询时,它会工作。但是,当它在我编写的函数中运行时,它会抱怨缺少一个。我还使用了表别名,希望它能解决这个问题,但事实并非如此

我从以下表格和行中获取信息

  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;