Question

Creating a postgresql function in fme - ERROR: unterminated dollar-quoted string at or near "$BODY$"

  • 12 March 2018
  • 2 replies
  • 86 views

Dear all

I am trying to compose a PostgreSQL function in FME using the SQLExecutor. My function installs correctly within pg admin, but since there is a dollar($) symbol included in the query, my function won't install correctly via FME and I receive the following error:

Error executing SQL command ('CREATE OR REPLACE FUNCTION gv.create_tables_from_foreign_schema(_foreign_schema character varying, _local_schema character varying)

  RETURNS void AS 

$BODY$'): 'ERROR:  unterminated dollar-quoted string at or near "$BODY$"

 

The function looks like this:

CREATE OR REPLACE FUNCTION $(p4_p3_schema).create_tables_from_foreign_schema(_foreign_schema character varying, _local_schema character varying)
  RETURNS void AS 
$BODY$;
declare
    selectrow record;
begin
for selectrow in
select 'CREATE TABLE ' || quote_ident(_local_schema) || '.' ||quote_ident(t.table_name) || ' AS SELECT * FROM ' || quote_ident(_foreign_schema) || '.' ||quote_ident(t.table_name) || '' AS qry 
from (
     SELECT table_name 
     FROM information_schema.tables
     WHERE table_schema = _foreign_schema
     )t
loop
execute selectrow.qry;
end loop;
end;
$BODY$;
  LANGUAGE plpgsql ;

 

Has any of you experience either creating functions or triggers, from within FME using the SQLExcecutor and have you been able to circumvent this problem of using "$"? It's obvious that the $ symbol is reserved for FME parameters, so I wonder if either I could alter that  FME setting or rewriting my SQL query?

 

 


2 replies

Userlevel 4

I assume that the workspace contains a private or published parameter called "p4_p3_schema", is that right?

Using that assumption, I was able to make it work by removing the semicolon after the two $BODY$-statements, e.g.

CREATE OR REPLACE FUNCTION $(p4_p3_schema).create_tables_from_foreign_schema(_foreign_schema character varying, _local_schema character varying)
  RETURNS void AS 
$BODY$
declare
    selectrow record;
begin
for selectrow in
select 'CREATE TABLE ' || quote_ident(_local_schema) || '.' ||quote_ident(t.table_name) || ' AS SELECT * FROM ' || quote_ident(_foreign_schema) || '.' ||quote_ident(t.table_name) || '' AS qry 
from (
     SELECT table_name 
     FROM information_schema.tables
     WHERE table_schema = _foreign_schema
     )t
loop
execute selectrow.qry;
end loop;
end;
$BODY$
LANGUAGE plpgsql ;

Tested with FME  2017.1.2.1

I assume that the workspace contains a private or published parameter called "p4_p3_schema", is that right?

Using that assumption, I was able to make it work by removing the semicolon after the two $BODY$-statements, e.g.

CREATE OR REPLACE FUNCTION $(p4_p3_schema).create_tables_from_foreign_schema(_foreign_schema character varying, _local_schema character varying)
  RETURNS void AS 
$BODY$
declare
    selectrow record;
begin
for selectrow in
select 'CREATE TABLE ' || quote_ident(_local_schema) || '.' ||quote_ident(t.table_name) || ' AS SELECT * FROM ' || quote_ident(_foreign_schema) || '.' ||quote_ident(t.table_name) || '' AS qry 
from (
     SELECT table_name 
     FROM information_schema.tables
     WHERE table_schema = _foreign_schema
     )t
loop
execute selectrow.qry;
end loop;
end;
$BODY$
LANGUAGE plpgsql ;

Tested with FME  2017.1.2.1

Hej david_r. You are right about the parameters. Initially, i did not have the semicolon after $BODY$ , but I guess that in my attempt to make it work, tried it out and it came in the code that I posted here. Now, I did make workbench work when I spread my SQL query across multiple SQLExecutors. I don't know why, but it seems that having multiple SQL database commands within one SQL executor might be a bit too much for FME to handle, so a stepwise procedure with multiple SQLExecutors, works in my experience well. At the end of my workbench I now only have an SQLExecutor that execute my function caller. 

 

 

0684Q00000ArMGxQAN.jpg

 

Reply