在 plpgsql 的存储过程中使用参数

1 postgresql syntax dynamic-sql plpgsql postgis

我正在尝试返回重叠多边形的数量。问题是它抱怨我的“$1”标志:

Error is "SQL state: 42601", syntax error at "$1". 
Run Code Online (Sandbox Code Playgroud)

为什么是这样?我在这里完全是初学者,除了用符号引用参数之外,我无法在网上找到解决方案$

CREATE OR REPLACE FUNCTION any_overlap (x text) 
RETURNS integer AS $$
DECLARE amount INTEGER;
BEGIN
    SELECT COUNT(*) INTO amount FROM $1 a
    INNER JOIN $1 b ON 
    (a.polygon && b.polygon AND ST_Relate(a.polygon, b.polygon, '2********'))
    WHERE a.ctid != b.ctid;
    RETURN amount AS id;
END; $$ LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 5

问题:

  1. 您无法在纯 SQL 中参数化标识符(例如表名)。EXECUTE为此,您需要使用动态 SQL 。
  2. amountinteger,但count()返回bigint
  3. RETURN amount AS id;是无效语法。要强制返回标量(而不是返回集合的函数)使用特定列名称,请使用参数OUT。例子:
  4. 我们谈论的是函数,而不是存储过程。看:

这个函数可以工作:

CREATE OR REPLACE FUNCTION any_overlap (_tbl regclass, OUT id bigint) 
  LANGUAGE plpgsql AS
$func$
BEGIN
   EXECUTE format(
   $q$
   SELECT count(*)
   FROM   %1$s a
   JOIN   %1$s b ON a.polygon && b.polygon AND st_relate(a.polygon, b.polygon, '2********')
   WHERE  a.ctid <> b.ctid
   $q$, _tbl)
   INTO id;
END
$func$;
Run Code Online (Sandbox Code Playgroud)

称呼:

SELECT any_overlap ('public.mytable');
Run Code Online (Sandbox Code Playgroud)

使用动态SQL时要警惕SQL注入!regclass请注意传递的表名称的类型。看: