【问题标题】:How to bind a SQL query return value to a psql variable?如何将 SQL 查询返回值绑定到 psql 变量?
【发布时间】:2012-07-25 16:20:57
【问题描述】:

背景:我正在为 PL/pgSQL 函数编写我的第一个 pgTAP 测试用例,并从 psql 测试脚本开始。没问题,但我在psql variables 上遇到了一点小烦恼。

在我的测试脚本中,我首先将大量测试数据转储到相关表中,然后使用由序列生成的主键引用数据。我发现能够创建一个包含主键的变量很方便。这就是我要找的:

scalasb=> \set the_id (select currval('id_data_id_seq'))
scalasb=> \echo :the_id
54754
scalasb=> 

但这就是我得到的:

scalasb=> \set the_id (select currval('id_data_id_seq'))
scalasb=> \echo :the_id
(selectcurrval('id_data_id_seq'))
scalasb=> 

我有一个解决方法(请参阅下面的示例),但看起来 psql 变量不是这项工作的正确工具。或者它们只是我在 Oracle sqlplus bind variables 中使用的不同...

所以我的问题是:如何将 SQL 查询的返回值绑定到 psql 脚本中的变量中?

我正在使用 9.1 的 linux。

-- this is a simplified example to illustrate the problem
begin;

create table id_data(id serial primary key, data text not null);

create or replace function get_text(p_id bigint)
returns text
as $$
declare
  v_data constant text := data from id_data where id = p_id;
begin
  return v_data;
end;
$$ language plpgsql;

insert into id_data(data) values('lorem ipsum');

-- this works correctly but is a rather verbose (especially when one have
-- more of these, in the same query/function)
select get_text((select currval('id_data_id_seq')));

-- instead I'd like to set the id to a variable and use that but this
-- seems to be impossible with psql, right ?
\set the_id (select currval('id_data_id_seq'))
\echo First try: :the_id
--select get_text(:the_id); -- this will fail

-- this works and reveals psql variables' true nature - they are just a
-- textual replacements
\set the_id '(select currval(\'id_data_id_seq\'))'
\echo Second try: :the_id
select get_text(:the_id);

rollback;

【问题讨论】:

    标签: postgresql psql


    【解决方案1】:

    恐怕你不能这样做 - 我为 psql 写了一些补丁,但它不在核心中

    您可以使用解决方法:

    postgres=# \set myvar `psql -A -t -c "select version()" postgres `
    postgres=# \echo :myvar
    PostgreSQL 9.1.4 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.7.0 20120507 (Red Hat 4.7.0-5), 64-bit
    

    【讨论】:

    • Argh ...所以看起来根本没有好的选择-无论如何都要感谢您的遵守。现在我将使用我自己的解决方法,因为多次执行 psql 看起来更奇怪。如何解决此问题的另一个想法是在安装中将所有序列设置为从 1000 开始,然后在单元测试脚本中将序列重置为 1。这样我就可以一直准确地知道测试数据的 ID,并且我可以依赖幻数。
    • 您可以在服务器端使用自定义会话变量
    • 自定义会话变量看起来有点矫枉过正,但temporary tables 的用法(我从这个question 学到)可能适合我的情况。下次我必须重构此代码时,我将探索这些选项。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-16
    • 2015-08-15
    • 2012-08-26
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多