Postgresql 使用dblink复制新数据的函数中出现语法错误

Postgresql 使用dblink复制新数据的函数中出现语法错误,postgresql,function,triggers,plpgsql,dblink,Postgresql,Function,Triggers,Plpgsql,Dblink,我从未在Postgres中创建过函数,我根据一些教程编写了此代码,但我不知道为什么会出错,控制台中的错误是: 我在Ubuntu上使用的是9.3.6版 CREATE OR REPLACE FUNCTION fn_replicate_insertof_students() RETURNS text AS $BODY$ BEGIN SELECT public.dblink_connect('hostaddr=127.0.0.1 port=5433 dbname=Ut

我从未在Postgres中创建过函数,我根据一些教程编写了此代码,但我不知道为什么会出错,控制台中的错误是:

我在Ubuntu上使用的是9.3.6版

CREATE OR REPLACE FUNCTION fn_replicate_insertof_students()
      RETURNS text AS
    $BODY$
    BEGIN
    SELECT public.dblink_connect('hostaddr=127.0.0.1 port=5433 dbname=Utiles user=postgres password=Mypass');

INSERT INTO res_partner (company_id,name,lang,comment,street,supplier,city,zip,country_id,email,phone,date,customer,mobile,ref,state_id,opt_out,city_id,l10n_mx_city2,l10n_mx_street3,l10n_mx_street4,notification_email_send,type,street2,active)
                        VALUES  (1,NEW.name,'es_MX',NEW.comment,NEW.street,false,NEW.city,NEW.zip,NEW.country_id,NEW.email,NEW.phone,NEW.date,true,NEW.mobile,NEW.ref,NEW.state_id,false,NEW.city_id,NEW.l10n_mx_city2,NEW.l10n_mx_street3,NEW.l10n_mx_street4,NEW.notification_email_send,NEW.type,NEW.street2,NEW.active));

SELECT public.dblink_disconnect();

END;
$BODY$ LANGUAGE sql VOLATILE SECURITY DEFINER
SET search_path=myschema, pg_temp;


CREATE TRIGGER tr_replicate_insertof_students
  AFTER INSERT 
  ON res_partner
  FOR EACH ROW
  EXECUTE PROCEDURE fn_replicate_insertof_students();

您已将函数标记为
语言sql
,这仅适用于包含单个sql语句的函数。此函数是用
语言plpgsql
编写的


它仍然会抱怨
SELECT
,因为
plpgsql
要求您实际处理
SELECT
的结果。您需要将
SELECT
替换为
PERFORM
,以明确放弃结果。

您已将函数标记为
语言sql
,这仅适用于包含单个sql语句的函数。此函数是用
语言plpgsql
编写的

它仍然会抱怨
SELECT
,因为
plpgsql
要求您实际处理
SELECT
的结果。您需要将
SELECT
替换为
PERFORM
,以明确放弃结果。

,但还有更多:

您的
搜索路径实际上是正确的<代码>pg_目录
会自动首先包括在内,除非您明确将其放在不同的位置

更重要的是,整个函数的当前形式是无意义的。您打开了一个dblink连接,但没有使用它。看起来您想加入
dblink\u exec()
。但是您需要首先将查询字符串与
NEW
表单中的值连接起来,因为
NEW
在虫洞的另一侧不可见。因此,您有一个很好的动态SQL示例。对于初学者来说,这是一个相当艰难的开始

在dba.SE上最近的相关回答中,详细的代码示例和对dblink函数的解释:

此外,这必须是一个用于触发器的命令。
您的函数可以如下工作:

CREATE OR REPLACE FUNCTION fn_replicate_insertof_students()
  RETURNS trigger AS
$func$
BEGIN
PERFORM public.dblink_connect('hostaddr=127.0.0.1 port=5433 
                dbname=Utiles user=postgres password=Mypass');

PERFORM public.dblink_exec(format(
   $f$INSERT INTO res_partner (company_id, name, lang, comment, ... )
      VALUES  (1, %L, 'es_MX', %L, ... )$f$
    , NEW.name, NEW.comment, ... ));

PERFORM public.dblink_disconnect();

RETURN NULL;  -- only ok for AFTER trigger

END
$func$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER
                        SET search_path=myschema, pg_temp;
ALTER FUNCTION fn_replicate_insertof_students() OWNER TO postgres;  -- guessing
创建或替换函数fn\u replicate\u insertof\u students()
将触发器返回为
$func$
开始
执行public.dblink_connect('hostaddr=127.0.0.1端口=5433
dbname=Utiles user=postgres password=Mypass');
执行public.dblink_exec(格式(
$f$插入res_partner(公司id、名称、语言、注释等)
值(1,%L,'es_MX',%L,…)$f$
,NEW.name,NEW.comment,…);
执行public.dblink_disconnect();
返回NULL;--仅适用于后触发器
结束
$func$语言plpgsql易失性安全定义程序
设置搜索路径=myschema,pg_temp;
将函数fn_replicate_insertof_students()所有者更改为postgres;——猜测
另外,请确保将所有者设置为正确的

考虑在目标服务器上使用
外部服务器
用户映射
和密码文件。详情请参阅

整个想法是一个相当昂贵的复制特例。对于表中的某些插入,这是可以的,但有。

,但还有更多:

您的
搜索路径实际上是正确的<代码>pg_目录
会自动首先包括在内,除非您明确将其放在不同的位置

更重要的是,整个函数的当前形式是无意义的。您打开了一个dblink连接,但没有使用它。看起来您想加入
dblink\u exec()
。但是您需要首先将查询字符串与
NEW
表单中的值连接起来,因为
NEW
在虫洞的另一侧不可见。因此,您有一个很好的动态SQL示例。对于初学者来说,这是一个相当艰难的开始

在dba.SE上最近的相关回答中,详细的代码示例和对dblink函数的解释:

此外,这必须是一个用于触发器的命令。
您的函数可以如下工作:

CREATE OR REPLACE FUNCTION fn_replicate_insertof_students()
  RETURNS trigger AS
$func$
BEGIN
PERFORM public.dblink_connect('hostaddr=127.0.0.1 port=5433 
                dbname=Utiles user=postgres password=Mypass');

PERFORM public.dblink_exec(format(
   $f$INSERT INTO res_partner (company_id, name, lang, comment, ... )
      VALUES  (1, %L, 'es_MX', %L, ... )$f$
    , NEW.name, NEW.comment, ... ));

PERFORM public.dblink_disconnect();

RETURN NULL;  -- only ok for AFTER trigger

END
$func$ LANGUAGE plpgsql VOLATILE SECURITY DEFINER
                        SET search_path=myschema, pg_temp;
ALTER FUNCTION fn_replicate_insertof_students() OWNER TO postgres;  -- guessing
创建或替换函数fn\u replicate\u insertof\u students()
将触发器返回为
$func$
开始
执行public.dblink_connect('hostaddr=127.0.0.1端口=5433
dbname=Utiles user=postgres password=Mypass');
执行public.dblink_exec(格式(
$f$插入res_partner(公司id、名称、语言、注释等)
值(1,%L,'es_MX',%L,…)$f$
,NEW.name,NEW.comment,…);
执行public.dblink_disconnect();
返回NULL;--仅适用于后触发器
结束
$func$语言plpgsql易失性安全定义程序
设置搜索路径=myschema,pg_temp;
将函数fn_replicate_insertof_students()所有者更改为postgres;——猜测
另外,请确保将所有者设置为正确的

考虑在目标服务器上使用
外部服务器
用户映射
和密码文件。详情请参阅


整个想法是一个相当昂贵的复制特例。对于表中的某些插入,这是可以的,但确实存在。

您得到的确切错误是什么?任何错误代码或完整的错误描述都有助于它的过程代码,因此语言应该是
plpgsql
,而不是
sql
。交叉发布到。唉,你到底犯了什么错误?任何错误代码或完整的错误描述都有助于它的过程代码,因此语言应该是
plpgsql
,而不是
sql
。交叉发布到。唉,哎呀。。。谢谢,我不知道为什么我认为有必要更改
搜索路径。。。谢谢,我不知道为什么我认为有必要更改
搜索路径。