3

PostgreSQLの関数が任意の型を返すようにする方法はありますか?

PLV8を使用して、PostgreSQL9.2のJSONタイプからフィールドを取得して比較しようとしています。

次の作品:

CREATE or replace FUNCTION jn (j json, key any ) RETURNS numeric 
LANGUAGE plv8   
IMMUTABLE 
AS $function$  
  var ej = JSON.parse(j);   
  if (typeof ej != 'object') return NULL;   
  return JSON.stringify(ej[key]);  
$function$;

SELECT * FROM things WHERE jn(data,'count') <= '10';

countフィールドが10未満の場所を返します。ただし、フィールドが数値でない場合は失敗します。jsonが保持する可能性のあるすべてのタイプのデータに対して特定の関数を作成したくないのですが、データ型を何らかの方法で推測して暗黙的にキャストする方法はありますか?

新しいPostgreSQLJSONデータ型内のフィールドを使用してクエリを実行するにはどうすればよいですか?も参照してください。

4

1 に答える 1

4

ポリモーフィック型の関数を探しているようです。タイプに関する上記のセクションと、このセクション
の最後の2つの例をお読みください。

keyパラメータと関数の出力のタイプは一致する必要があることに注意してください。これが当てはまらない場合は、おそらく戻っtextてから、関数の外で正しい型にキャストする必要があります。

私はこれがあなたのために仕事をするだろうと思います:

CREATE or replace FUNCTION jn (j json, key anyelement ) RETURNS anyelement
LANGUAGE plv8   
IMMUTABLE 
AS $function$  
  var ej = JSON.parse(j);   
  if (typeof ej != 'object') return NULL;   
  return JSON.stringify(ej[key]);  
$function$;

申し訳ありませんが、9.2サーバーがないため、これをテストできません。


編集:

関数内でキャストを実行する前に、まず関数を作成する必要があります。作成時の関数の入力パラメータの型と戻り型は固定されています。これは、2つの可能性しかないことを意味します。

  • typeを使用します。これにより、関数から返されるのと同じタイプのパラメーターanyelementが強制されます。key
  • typeを使用textし、関数の外に結果をキャストします。

PLV8まだ型をサポートしていないので、実際にそのanyelement上にPL / pgSQLでラッパー関数を作成して、次の作業を行うことができます。

CREATE FUNCTION jn_wrap(jn varchar, key anyelement, OUT ret anyelement)
    AS $js_wrap$
BEGIN
    EXECUTE 'SELECT CAST(jn($1, $2) AS '||pg_typeof(key)||')'
        USING jn, key INTO ret;

    RETURN ;
END;
$js_wrap$ LANGUAGE plpgsql;

かなり典型的なことかもしれませんが、そのkeyタイプは目的のリターンタイプとは異なります。

于 2012-05-13T12:46:39.520 に答える