Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 函数返回具有动态列名的行集_Postgresql - Fatal编程技术网

Postgresql 函数返回具有动态列名的行集

Postgresql 函数返回具有动态列名的行集,postgresql,Postgresql,我有一个通用的键/值表,我想在一个函数中预处理它以按键过滤,然后根据键命名值 该表是这样的,id指向另一个表(但实际上是不关心这个问题): 等等。键值可能不同,并且并非所有ID都使用相同的键 具体来说,我想做的是创建一个函数,该函数将生成与给定键匹配的行。然后,它将为每个匹配的键返回一行,并使用该键命名值 因此,给定key name参数'x'的函数输出将与我执行以下命令时相同: SELECT id, value x FROM keyed_values WHERE key = 'x'; id |

我有一个通用的键/值表,我想在一个函数中预处理它以按键过滤,然后根据键命名值

该表是这样的,
id
指向另一个表(但实际上是不关心这个问题):

等等。键值可能不同,并且并非所有ID都使用相同的键

具体来说,我想做的是创建一个函数,该函数将生成与给定键匹配的行。然后,它将为每个匹配的
返回一行,并使用该键命名

因此,给定key name参数
'x'
的函数输出将与我执行以下命令时相同:

SELECT id, value x FROM keyed_values WHERE key = 'x';
 id |         x
----+-------------------
  1 | Value for x for 1
  2 | Value for x for 2
(2 rows)
以下是我的观点,从其他一些SO答案中总结出来:

CREATE FUNCTION value_for(key TEXT) RETURNS SETOF RECORD AS $$
    BEGIN
        RETURN QUERY EXECUTE format('SELECT id, value %I FROM keyed_values WHERE key = %I', key, key);
    END;
$$ LANGUAGE 'plpgsql';
该功能已被接受。但是当我执行它时,我得到了这个错误:

SELECT * FROM value_for('x');
ERROR:  a column definition list is required for functions returning "record"
LINE 1: SELECT * FROM value_for('x');

我明白它告诉我的,但不知道如何解决。如何动态定义输出列名?

WHERE
子句中使用的
键不是标识符,而是文本,因此函数应该如下所示:

CREATE FUNCTION value_for(key TEXT) RETURNS SETOF RECORD AS $$
    BEGIN
        RETURN QUERY EXECUTE format('SELECT id, value %I FROM keyed_values WHERE key = %L', key, key);
    END;
$$ LANGUAGE plpgsql;

如果已将函数定义为返回记录数据类型,则必须存在别名或关键字as,后跟格式为的列定义列表(列名称数据类型[,…])。列定义列表必须与函数返回的实际列数和类型匹配

使用列定义列表:

SELECT * FROM value_for('x') AS (id int, x text);
请注意,您不需要动态SQL或plpgsql,因为列名称在上面的列表中定义。简单SQL函数应该快一点:

CREATE OR REPLACE FUNCTION value_for(_key text)
RETURNS SETOF RECORD AS $$
    SELECT id, value
    FROM keyed_values
    WHERE key = _key
$$ LANGUAGE SQL;
如果您不喜欢被强制为每个函数调用追加列定义列表,则可以从函数返回一个表:

CREATE OR REPLACE FUNCTION value_for_2(_key text)
RETURNS TABLE(id int, x text) AS $$
    SELECT id, value
    FROM keyed_values
    WHERE key = _key
$$ LANGUAGE SQL;

SELECT * FROM value_for_2('x');

 id |         x         
----+-------------------
  1 | Value for x for 1
  2 | Value for x for 2
(2 rows)    

然而,这并不能解决问题。无法动态定义从函数返回的列名。在执行查询之前,必须指定返回列的名称和类型。

您不能这样做。列名来自函数定义,或者在调用时必须命名列。
CREATE OR REPLACE FUNCTION value_for_2(_key text)
RETURNS TABLE(id int, x text) AS $$
    SELECT id, value
    FROM keyed_values
    WHERE key = _key
$$ LANGUAGE SQL;

SELECT * FROM value_for_2('x');

 id |         x         
----+-------------------
  1 | Value for x for 1
  2 | Value for x for 2
(2 rows)