postgresql 在Perl脚本中执行psql时,在“$$”处或其附近未终止的美元引号字符串

lfapxunr  于 2024-01-07  发布在  PostgreSQL
关注(0)|答案(1)|浏览(192)

我在perl脚本中使用以下命令来执行sql语句:

my $cmd = "PGPASSWORD=$pw  /usr/bin/psql  -h ${host} -p ${port} -d ${dbname} -U ${user} -c '${dropTblsSql}' -q  >> logfile.log"
my $out = `$cmd`;

字符串
sql语句包含在$dropTblSql变量中:

my $dropTblsSql = "
DO $$
 DECLARE 
  r record;
BEGIN
   FOR r IN SELECT quote_ident(tablename) AS tablename, quote_ident(schemaname) AS schemaname FROM pg_tables WHERE schemaname = 'rbm_pu7_mdt'
   LOOP
     EXECUTE format('DROP TABLE IF EXISTS %I.%I CASCADE', r.schemaname, r.tablename);
   END LOOP;
END;
$$ LANGUAGE plpgsql;
";


SQL语句的执行失败,出现Unterminated dollar-quoted string at or near "$$错误。我尝试转义美元符号(\$\$),用单引号替换它们(并将其他单引号加倍)。唯一有效的方法是从文件(-f path_to_file)中打开语句,但如果可能的话,我想避免该选项。
有人知道如何解决双美元报价字符串问题吗?

b5buobof

b5buobof1#

你的陈述可能会在其中的单引号处被切断。尝试用命名的美元引号替换它们:

my $dropTblsSql = '
DO $do_block$
 DECLARE 
  r record;
BEGIN
   FOR r IN SELECT quote_ident(tablename) AS tablename, quote_ident(schemaname) AS schemaname FROM pg_tables WHERE schemaname = $abc$rbm_pu7_mdt$abc$
   LOOP
     EXECUTE format(
               $dynamic_sql$
               DROP TABLE IF EXISTS %I.%I CASCADE
               $dynamic_sql$
              , r.schemaname, r.tablename);
   END LOOP;
END;
$do_block$ LANGUAGE plpgsql;
';

字符串
正如ikegami所指出的,您可能更喜欢使用PGPASSFILE并将实用程序指向正确的路径,而不是暴露PGPASSWORD

相关问题