plpgsql函数内部的变量替换

为了能够在一个数据库内创建应用程序的不同实例,例如测试阶段,我想使用变量作为模式名称。创建表或序列时一切正常,但是我无法弄清楚在函数中使用变量的一种优雅方式。我已经看过一些文章 关于用美元报价的字符串常量,但我仍然希望找到一个解决方案。

当前正在运行PostgreSQL11。

代码如下:

按预期方式工作,将schema_name设置为sc并在DDL期间使用变量:

\set schema_name sc

CREATE SEQUENCE :schema_name.S_VT_KEY INCREMENT BY 1 START WITH 1 CACHE 1 NO CYCLE OWNED BY NONE;

create table :schema_name.vartest (
  VT_KEY   BIGINT,DESCRIPTION TEXT);

现在是功能:

create or replace function :schema_name.fvartest(
  p_desc  TEXT)
  RETURNS bigint
  language 'plpgsql'
  COST 100.0
  VOLATILE NOT LEAKPROOF
AS $function$
DeclARE
  p_key bigint;
BEGIN

  select nextval('sc.S_VT_KEY') into p_key; -- (1)

  insert into sc.vartest (VT_KEY,DESCRIPTION) -- (2)
      values (p_key,p_desc);

  return p_key;

END $function$;

万一(1) 我想使用类似的东西:

  select nextval(:schema_name || '.S_VT_KEY') into p_key;

如果(2)

  insert into :schema_name.vartest (VT_KEY,DESCRIPTION) -- (2)

到目前为止,任何变体都会产生错误消息:

直接使用:

select nextval(:schema_name || '.S_VT_KEY') into p_key; 

提供语法错误

psql:test/testcase001.sql:29: ERROR:  syntax error at or near ":"
LINE 12:  select nextval(:schema_name || '.S_VT_KEY') into p_key; -- ...

转义,编译但不运行:

select nextval($e$:schema_name$e$ || '.S_VT_KEY') into p_key; -- (1)

CONTEXT:  SQL statement "select nextval($e$:schema_name$e$ || '.S_VT_KEY')"

几乎使用相同的定界符替换了变量,但确实出现语法错误:

select nextval($function$ :'schema_name' $function$ || '.S_VT_KEY') into p_key; -- (1)

LINE 12:  select nextval($function$ 'sc' $function$ || '.S_VT_KEY')

PostgreSQL 12中也许有办法吗?

wtuuser 回答:plpgsql函数内部的变量替换

我想出了一个目前可以使用的解决方案,但是到目前为止还不够完善。我正在使用bash变量替换,它似乎适用于上述两种情况:

#!/bin/bash

export schema_name="sc"

psql postgresql://<user>:<pwd>@<host>/<db>  << EOF


create or replace function ${schema_name}.fvartest(
  p_desc  TEXT)
  RETURNS bigint
  language 'plpgsql'
  COST 100.0
  VOLATILE NOT LEAKPROOF
AS \$function\$
DECLARE
    p_key bigint;
BEGIN

    select nextval('${schema_name}.S_VT_KEY') into p_key; -- (1)

    insert into ${schema_name}.vartest (VT_KEY,DESCRIPTION) -- (2)
        values (p_key,p_desc);

    return p_key;

END \$function\$;

    select ${schema_name}.fvartest('bla bla');
    select * from ${schema_name}.vartest;

EOF

但是现在我必须将代码放入bash脚本中,并转义$ function $ Postges样式的$$表示法。也许还有更好的方法,希望收到您的来信。

本文链接:https://www.f2er.com/3150012.html

大家都在问