我正在研究一个使用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
中是一个不同的上下文,但是肯定有一种方法可以在所有地方编写此模式名称吗?
答案 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)
在带引号的SQL文字和标识符中不会执行变量插值。因此,诸如
import {Component} from '@angular/core'; @Component({...}) export class SliderOverviewExample { someValue = 0; }
之类的构造不适用于从变量的值中产生带引号的文字(并且如果起作用,将是不安全的,因为它将无法正确处理值中嵌入的引号)。 / p>
现在,功能主体为“美元报价的%rdquo;字符串文字(':foo'
),因此该变量不会在那里被替换。
我想不出一种使用$BODY$...$BODY$
变量的方法。