在PostgreSQL执行语句中使用变量

时间:2018-07-05 13:39:44

标签: postgresql dynamic plpgsql

在创建触发函数时,我试图提供一个参数。

我一直在尝试使用以下代码:

DO $DO$
BEGIN
EXECUTE format($TRIGGER$
  CREATE OR REPLACE FUNCTION my_schema.my_trigger_fcn() RETURNS trigger AS
  $BODY$
    DECLARE
      my_geom geometry(MultiPoint,%1$s);
    BEGIN
      my_geom = st_collect(NEW.situation_geometry)::geometry(MultiPoint,%$1s);
      NEW.geometry = my_geom;
      RETURN NEW;
    END;
  $BODY$
  LANGUAGE plpgsql;
$TRIGGER$, :SRID);
END
$DO$;

,并尝试使用psql -v SRID=2056 -f myfile运行此代码。 但是我收到语法错误。

我还尝试了SQL execute命令,但是准备好的语句是not allowed,用于创建触发函数。

有什么主意吗?


解决方案

感谢@Pavel Stehule,这是有效的代码:

SELECT set_config('my.srid', :SRID::text, false);
DO $DO$
BEGIN
EXECUTE format($TRIGGER$
  CREATE OR REPLACE FUNCTION qgep_od.my_trigger_fcn() RETURNS trigger AS
  $BODY$
    DECLARE
      my_geom geometry(MultiPoint,%1$s);
    BEGIN
      my_geom = st_collect(NEW.situation_geometry)::geometry(MultiPoint,%1$s);
      NEW.geometry = my_geom;
      RETURN NEW;
    END;
  $BODY$
  LANGUAGE plpgsql;
$TRIGGER$, current_setting('my.srid'));
END
$DO$;

1 个答案:

答案 0 :(得分:1)

您不能在任何SQL字符串中使用psql变量。该字符串也是DO命令的主体。您可以使用会话变量:

\set myvar xxx
select set_config('my.myvar', :'myvar', false); 
do $$
begin
  execute format('create or replace function fx() returns void as $_$begin raise notice %L; end$_$ language plpgsql', current_setting('my.myvar')); 
end;
$$;

postgres=# \sf fx
CREATE OR REPLACE FUNCTION public.fx()
RETURNS void
LANGUAGE plpgsql
AS $function$begin raise notice 'xxx'; end$function$

其他可能性是在psql之前进行此替换-您可以使用sed