如何在Postgres脚本中使用变量?

时间:2018-11-20 16:17:42

标签: postgresql psql variable-expansion

我正在研究一个使用Postgres作为后端的原型。我并没有做很多SQL,所以感觉很不错。我制作了一个与.pgsql一起运行的psql文件,该文件执行设置数据库的许多文件中的每个文件,并且我使用一个变量来定义将要使用的架构,因此我可以在不破坏功能的情况下测试功能我的“好”实例:

\set schema_name 'example_schema'

\echo 'The Schema name is' :schema_name

\ir sql/file1.pgsql
\ir sql/file2.pgsql

这一直很好。我定义了几个可以正确扩展:schema_name的函数:

CREATE OR REPLACE FUNCTION :schema_name.get_things_by_category(...

出于我不知道的原因,这在我的最新功能中不起作用:

CREATE OR REPLACE FUNCTION :schema_name.update_thing_details(_id uuid, _details text)
    RETURNS text
    LANGUAGE 'plpgsql'
AS $BODY$

BEGIN
    UPDATE :schema_name.things
    ...

语法错误表明它实际上是在:schema_name之后解释UPDATE而不是对其进行扩展。我如何在这里使用变量值而不是文字值?我知道也许在BEGIN..END中是一个不同的上下文,但是肯定有一种方法可以在所有地方编写此模式名称吗?

2 个答案:

答案 0 :(得分:1)

我可以想到三种方法,因为psql无法直接做到这一点。

Shell脚本

使用bash脚本执行变量替换,然后将结果通过管道传递到psql中。

#!/bin/bash

$schemaName = $1
$contents = `cat script.sql | sed -e 's/@SCHEMA_NAME@/$schemaName'`

echo $contents | psql

如果您有很多.sql脚本,这可能是很多样板。

登台模式

使用诸如staging之类的硬编码模式来保持您现在的方法,然后执行bash脚本,并将staging重命名为您想要的实际模式。

自定义搜索路径

您的入口点可能是bash中的内联脚本,该内联脚本通过管道传递到psql,对默认的连接模式进行前期更新,然后使用\ ir包含所有.sql文件,该文件应< em>不是指定架构。

#!/bin/bash

$schemaName = $1

psql <<SCRIPT
SET search_path TO $schemaName;
\ir sql/file1.pgsql
\ir sql/file2.pgsql
SCRIPT

一些详细信息:How to select a schema in postgres when using psql?

我个人倾向于后一种方法,因为它似乎是最简单且可扩展的。

答案 1 :(得分:0)

The documentation说:

  

在带引号的SQL文字和标识符中不会执行变量插值。因此,诸如import {Component} from '@angular/core'; @Component({...}) export class SliderOverviewExample { someValue = 0; } 之类的构造不适用于从变量的值中产生带引号的文字(并且如果起作用,将是不安全的,因为它将无法正确处理值中嵌入的引号)。 / p>

现在,功能主体为“美元报价的%rdquo;字符串文字(':foo'),因此该变量不会在那里被替换。

我想不出一种使用$BODY$...$BODY$变量的方法。

相关问题