如何在psql中使用脚本变量?
时间:2020-03-05 18:45:41 来源:igfitidea点击:
在MS SQL Server中,我创建了脚本以使用可自定义的变量:
DECLARE @somevariable int SELECT @somevariable = -1 INSERT INTO foo VALUES ( @somevariable )
然后,我将在运行时更改@somevariable的值,具体取决于我在特定情况下所需的值。由于它位于脚本的顶部,因此很容易看到和记住。
我如何对PostgreSQL客户端psql
做同样的事情?
解决方案
回答
FWIW,真正的问题是我在\ set命令的末尾添加了分号:
\set owner_password 'thepassword';
分号被解释为变量中的实际字符:
\echo :owner_password thepassword;
因此,当我尝试使用它时:
CREATE ROLE myrole LOGIN UNENCRYPTED PASSWORD :owner_password NOINHERIT CREATEDB CREATEROLE VALID UNTIL 'infinity';
...我懂了:
CREATE ROLE myrole LOGIN UNENCRYPTED PASSWORD thepassword; NOINHERIT CREATEDB CREATEROLE VALID UNTIL 'infinity';
这不仅无法在文字周围设置引号,而且将命令分为两部分(第二部分无效,因为它以" NOINHERIT"开头)。
这个故事的寓意:PostgreSQL"变量"实际上是文本扩展中使用的宏,而不是真正的值。我敢肯定这会派上用场,但起初是很棘手的。
回答
关于PSQL变量的最后一句话:
- 如果将它们用SQL语句括在单引号中,则它们不会扩展。因此,这是行不通的:
SELECT * FROM foo WHERE bar = ':myvariable'
- 要在SQL语句中扩展为字符串文字,我们必须在变量集中包括引号。但是,变量值已经必须用引号引起来,这意味着我们需要第二组引号,并且必须对内部引号进行转义。因此,我们需要:
\set myvariable '\'somestring\'' SELECT * FROM foo WHERE bar = :myvariable
编辑:从PostgreSQL 9.1开始,我们可以改写:
\set myvariable somestring SELECT * FROM foo WHERE bar = :'myvariable'
回答
我们需要使用一种过程语言,例如PL / pgSQL,而不是SQL proc语言。
在PL / pgSQL中,我们可以在SQL语句中直接使用vars。
对于单引号,可以使用引号文字函数。
回答
Postgres变量是通过\ set命令创建的,例如...
\set myvariable value
...,然后可以替换为...
SELECT * FROM :myvariable.table1;
... 或者 ...
SELECT * FROM table1 WHERE :myvariable IS NULL;
...,但是,如果我们要将变量用作条件字符串查询中的值,例如...
SELECT * FROM table1 WHERE column1 = ':myvariable';
...则我们需要在变量本身中包含引号,因为上述内容将无法正常工作。而是这样定义变量...
\set myvariable 'value'
但是,如果像我一样,我们遇到了要从现有变量中创建字符串的情况,我发现诀窍是...
\set quoted_myvariable '\'' :myvariable '\''
现在,我们同时具有相同字符串的带引号和不带引号的变量!而且你可以做这样的事情....
INSERT INTO :myvariable.table1 SELECT * FROM table2 WHERE column1 = :quoted_myvariable;