2017-11-09 9 views
1

私は、一連のテキストを返すPostgreSQLにplpython3u関数を書きたいと思います。私は私に奇妙に見える難点を見つけた。マニュアルに従って、私は以下を行うことができます:PostgreSQL:plpython3uで単一値を返す関数を返す

drop schema if exists X cascade; 
create schema X; 

create type X.greeting AS (
    who text 
); 

create function X.greet(how text) 
    returns setof X.greeting language plpython3u as $$ 
    for who in [ 'World', 'PostgreSQL', 'PL/Python' ]: 
    yield (who,) 
    $$; 

これは、1つのテキストを持つ行のセットを返すPython関数です。あまりにも多くの作品、私は期待される出力を得る:

select X.greet('helo'); 

    greet  
-------------- 
(World) 
(PostgreSQL) 
(PL/Python) 
(3 rows) 

select * from X.greet('helo'); 

    who  
------------ 
World 
PostgreSQL 
PL/Python 
(3 rows) 

これまでのところとても良い。

create function X.pairs_of_integers_A(out integer, out integer) 
    returns setof record language plpython3u as $$ 
    return [ (12, 24,), (36, 48,), (60, 72,) ] 
    $$; 

create function X.pairs_of_integers_B(out integer, out integer) 
    returns setof record language plpython3u as $$ 
    for pair in [ (12, 24,), (36, 48,), (60, 72,) ]: 
    yield pair 
    $$; 

select * from X.pairs_of_integers_A(); 
select * from X.pairs_of_integers_B(); 

column1 | column2 
---------+--------- 
     12 |  24 
     36 |  48 
     60 |  72 
(3 rows) 

column1 | column2 
---------+--------- 
     12 |  24 
     36 |  48 
     60 |  72 
(3 rows) 

は、今、私たちはに来る:しかし、私は目的のためにテーブル定義を記述する必要はありません、私は(整数を使用するために起こりますが、それでもこれは)この例のように、代わりにsetof recordを使用したいです興味深い部分。上記から一般化すると、以下の1つまたは複数の式が正しいはずです:単一の値のセットを返すには、Pythonタプルのリスト、Python番号のリストを返すか、または単一値を持つタプルまたは値:

create function X.single_integers_A(out integer) 
    returns setof record language plpython3u as $$ 
    return [ (12,), (36,), (60,), ] 
    $$; 

create function X.single_integers_B(out integer) 
    returns setof record language plpython3u as $$ 
    return [ 12, 36, 60, ] 
    $$; 

create function X.single_integers_C(out integer) 
    returns setof record language plpython3u as $$ 
    for n in [ (12,), (36,), (60,), ] 
    yield n 
    $$; 

create function X.single_integers_D(out integer) 
    returns setof record language plpython3u as $$ 
    for n in [ 12, 36, 60, ] 
    yield n 
    $$; 

もをコンパイル上記のどれも判明していないが、彼らはすべてのSQLパーサが原因OUTパラメータの整数でなければなりません関数の結果タイプで投げるさせます。私はSQLパーサはPythonの関数の内部で見ていないので、これは

that-疑うために私をリードそれはreturns setof recordと単一outパラメータの両方で関数を定義するために、PostgreSQLでは、不可能です。代わりに、出力タイプは常にテーブル(または同様の手段)として定義する必要があります

誰でも私を修正してください。もしこれが真実になるのであれば、本当に迷惑でしょう。確かにどこかで間違いを犯した?

+0

はい - 関数はパラメータを持ち、voidを返す、または何かを返していないと私は –

+0

https://www.postgresql.org/docs/current/static/plpgsql-control-structures考えるパラメータを何を持っているのどちらか。 html –

+0

1)コメントありがとうございます2)関連リンクはhttps://www.postgresql.org/docs/current/static/plpython-data.html#idm46428683116992です3)ドキュメントでは「OUTパラメータで関数をセットするRETURNS SETOFレコードを使用して)もサポートされています。 " - そうです、out-parameters + returns-setof-recordは問題です。 –

答えて

1

あなただけの整数の集合返す必要があります。the documentationパー

create or replace function x.single_integers() 
returns setof integer language plpython3u as $$ 
    return [ 12, 36, 60 ] 
$$; 

select * from x.single_integers(); 

single_integers 
----------------- 
       12 
       36 
       60 
(3 rows)  

(強調追加):

ここで重要なポイントは、あなたがその関数のリターンを示すために、レコードSETOF RETURNSを書かなければならないということです1つではなく複数の行。 出力パラメータが1つだけの場合は、レコードの代わりにそのパラメータの型を記述します。

+0

私は安心しました。バグ/監視/ SQLの矛盾ではなく、SQLの理解にラクナを発見しました。 –