【问题标题】:plpgsql associative array argumnentplpgsql 关联数组参数
【发布时间】:2012-04-08 07:22:42
【问题描述】:

我曾经在邮件列表http://archives.postgresql.org/pgsql-hackers/2005-06/msg01481.php读过这篇文章

SELECT *
FROM foo_func(
    c => current_timestamp::timestamp with time zone,
    a => 2,
    b => 5
);

现在我需要这种可以将关联数组参数传递给函数的解决方案。 我是否需要制作一个虚拟表,然后将该表用作参数类型?或者有什么直接的解决方法吗?或者这个黑客已经实施了吗?

或者我可以使用 pl/python 来模拟吗?

【问题讨论】:

  • 您的意思是要将 hstore 值传递给函数吗? postgresql.org/docs/9.0/static/hstore.html
  • 嗯不错的选择但是我得到ERROR: type "hstore" does not exist我正在使用8.4
  • 啊,我想那时候它只是一个contrib模块。如果你安装它应该可以工作。 postgresql.org/docs/8.4/static/hstore.html
  • 好吧,我签入了SELECT * FROM pg_available_extensions,但上面写着no such relation pg_available_extensions,你能告诉我如何安装它或检查它是否安装了吗?
  • 扩展是 9.1+ 的功能。我已将 8.4 的详细说明与代码示例放在单独的答案中。

标签: postgresql stored-procedures plpgsql


【解决方案1】:

以下是使用 hstore 和 PG-8.4 for debian 回答的步骤。

1) 如果尚未安装,请安装 contrib 包

# apt-get 安装 postgresql-contrib-8.4

2)在相关数据库中安装hstore

$ psql -U postgres -d 数据库名 # \i /usr/share/postgresql/8.4/contrib/hstore.sql

2bis) 如果没有安装plpgsql语言,安装它(仍然在psql中作为postgres用户)

# 创建语言 plpgsql;

3) 创建以 hstore 作为输入的函数。这是 plpgsql 中的一个示例,它仅枚举键和值:

CREATE OR REPLACE function enum_hstore(in_h hstore) returns void
as $$
declare
  kv record;
begin
  for kv in select * from (select (each(in_h)).*) as f(k,v) loop
    raise notice 'key=%,value=%',kv.k,kv.v;
  end loop;
end
$$ language plpgsql;

4) 调用函数。由于键和值是文本类型,因此可能需要将非文字条目转换为文本,就像问题中的 current_timestamp 调用一样。示例:

  select enum_hstore(
    hstore('c',current_timestamp::text) ||
    'a=>2,b=>5'::hstore
  );

上述函数的预期结果:

 注意:key=a,value=2
 注意:键=b,值=5
 注意:key=c,value=2012-04-08 16:12:59.410056+02

【讨论】:

  • 获取:语言 plpgsql 在第 3 步中不存在
  • 那么步骤#2应该有额外的SQL命令:CREATE LANGUAGE plpgsql
  • 现在我遇到了一个大错误。 ERROR: syntax error at or near "CREATE" LINE 2: CREATE OR REPLACE function enum_hstore(in_h hstore) returns ... 旁注:如果我尝试使用language sql,我会得到syntax error at or near "record"
  • 我看不出语法错误在哪里。这个对我有用。至于sql语言,这里没有选择,需要过程代码。
  • 我是否需要做任何其他事情,比如为语言 plpgsql 设置处理程序?还是我错过了什么?
【解决方案2】:

这是在version 9.0中实现的:

4.3.2。使用命名符号

在命名符号中,每个参数的名称使用 := 来指定 将其与参数表达式分开。例如:

SELECT concat_lower_or_upper(a := 'Hello', b := 'World');
 concat_lower_or_upper 
-----------------------
 hello world
(1 row)

【讨论】:

  • 谢谢,但我运行的是 8.4,我会在稳定的 debian 版本中获得 9.0 吗?以及如何在函数中处理这些键值对?
  • 但是名称 a 和 b 必须是函数内部参数的名称,不是吗?我不确定,但我认为 Neel 的问题想将任意关联数组传递给函数(不过我可能是错的)。
  • 是的,我需要传递任意关联数组而不是参数。如果我的问题导致不同的含义,我很抱歉
猜你喜欢
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
  • 2012-03-26
  • 2016-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-09
相关资源
最近更新 更多