0

この plpgsql 関数を作成しましたが、何も返されません! 一方、クエリ部分を取り出して別のSQLウィンドウでこれを実行すると、正しい行が返されます。

また、クエリは実際には最適ではないと思うので、助けていただければ幸いです(plpgsqlにとって非常に新しい)

CREATE OR REPLACE FUNCTION get_members(in_company_uuid uuid, in_start integer, in_limit integer, in_sort character varying, in_order character varying, OUT out_status integer, OUT out_status_description character varying, OUT out_value character varying[]) RETURNS SETOF record
LANGUAGE plpgsql
AS $$DECLARE

temp_record RECORD;
temp_out_value VARCHAR[];
temp_iterator INTEGER := 0;

BEGIN

FOR temp_record IN EXECUTE '
SELECT DISTINCT ON
(' || in_sort || ')
u.user_uuid,
u.firstname,
u.preposition,
u.lastname,
array(SELECT email FROM emails WHERE user_uuid = u.user_uuid) as emails,
array(SELECT mobilenumber FROM mobilenumbers WHERE user_uuid = u.user_uuid) as mobilenumbers,
array(SELECT c.name FROM targetgroupusers AS tgu LEFT JOIN membercategories as mc ON mc.targetgroup_uuid = tgu.targetgroup_uuid LEFT JOIN categories AS c ON mc.category_uuid = c.category_uuid WHERE tgu.user_uuid = u.user_uuid) as categories,
array(SELECT color FROM membercategories WHERE targetgroup_uuid IN(SELECT targetgroup_uuid FROM targetgroupusers WHERE user_uuid = u.user_uuid)) as colors
FROM
    membercategories AS mc
LEFT JOIN
    targetgroups AS tg
ON
    tg.targetgroup_uuid = mc.targetgroup_uuid
LEFT JOIN
    targetgroupusers AS tgu
ON
    tgu.targetgroup_uuid = tg.targetgroup_uuid
LEFT JOIN
    users AS u
ON
    u.user_uuid = tgu.user_uuid
WHERE
    mc.company_uuid = \'' || in_company_uuid || '\'
ORDER BY
   ' || in_sort || ' ' || in_order || '
OFFSET
    ' || in_start || '
LIMIT
    ' || in_limit

LOOP
  temp_out_value[temp_iterator] = ARRAY[temp_record.user_uuid::VARCHAR(36), temp_record.firstname::CHARACTER VARYING, temp_record.preposition::CHARACTER VARYING, temp_record.lastname::CHARACTER VARYING, temp_record.emails::CHARACTER VARYING, temp_record.mobilenumbers::CHARACTER VARYING, temp_record.categories::CHARACTER VARYING, temp_record.colors::CHARACTER VARYING];
  temp_iterator = temp_iterator+1;
END LOOP;

out_status := 0;
out_status_description := 'Members retrieved';
out_value := temp_out_value;
RETURN;

END$$;

どうもありがとう!

4

3 に答える 3

1

RETURN NEXT temp_record完全な結果セットを返すには、「ただの」RETURN の代わりに使用する必要があります。

これは、「RETURNS SETOF」関数の処理方法を説明するマニュアルの一部です。

その場合、返される個々のアイテムは、一連の RETURN NEXT または RETURN QUERY コマンドによって指定され、引数なしの最後の RETURN コマンドを使用して、関数の実行が終了したことを示します。

于 2010-12-13T14:22:10.143 に答える
0

使用する必要があります

CREATE OR REPLACE FUNCTION get_members(...) RETURNS record LANGUAGE plpgsql AS
...

つまり、setofa_horse が言及しているように、あなたの問題であるを削除します

ただし、このように 1 行しか得られないことに注意してください。次の例に従って、複数の行が必要な場合は、その配列のネストを解除できます。

create or replace function unnest(anyarray) returns setof anyelement as $$
  select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) i;
$$ language'sql' immutable;

create function func(out text, out text[]) returns record language plpgsql as $$
begin
  $1='success';
  $2[1]='hello';
  $2[2]='there';
  $2[3]='Koen';
  return;
end;$$;

select * from unnest((select column2 from func()));

 unnest
--------
 hello
 there
 Koen

unnest8.4 以降を使用している場合は、ここで行ったように独自の関数を作成する必要はありません。

于 2010-12-13T16:54:56.423 に答える
0

\ を使用してエスケープしないでください。引用符を使用してください。

\'' || in_company_uuid || '\'

''' || in_company_uuid || '''

ただし、これには関数を使用しません。単純な SQL クエリだけです。EXPLAIN を使用して、それがどのように実行され、どこでパフォーマンスの問題が見つかるかを確認してください。それはあまりいいSQLではありません...

Ps。関数は SQL インジェクションに対しても脆弱です。ユーザー入力を SQL にエスケープせずに入れます。

于 2010-12-13T14:34:19.503 に答える