61

PL/pgSQL で関数を作成しています。行が存在するかどうかを確認する最も簡単な方法を探しています。
現在、 anintegerを abooleanに SELECT していますが、実際には機能しません。私はPL/pgSQLの経験が十分ではなく、これを行う最善の方法をまだ知りません。

これが私の機能の一部です:

DECLARE person_exists boolean;
BEGIN

person_exists := FALSE;

SELECT "person_id" INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists THEN
  -- Do something
END IF;

END; $$ LANGUAGE plpgsql;

更新- 私は今のところこのようなことをしています:

DECLARE person_exists integer;
BEGIN

person_exists := 0;

SELECT count("person_id") INTO person_exists
  FROM "people" p
WHERE p.person_id = my_person_id
LIMIT 1;

IF person_exists < 1 THEN
  -- Do something
END IF;
4

2 に答える 2

172

よりシンプルに、より短く、より速く: EXISTS .

IF EXISTS (SELECT 1 FROM people p WHERE p.person_id = my_person_id) THEN
  -- do something
END IF;

クエリ プランナーは、見つかった最初の行で停止できますcount()。これは、すべての (一致する) 行を関係なくスキャンするのとは対照的です。大きなテーブルとの違いを生みます。一意の列の条件の場合、違いはわずかです。1 つの行のみが適格であり、それをすばやく検索するためのインデックスがあります。

コメントの@a_horse_with_no_nameからの入力で改善されました。

空のSELECTリストを使用できます。

IF EXISTS (SELECT FROM people p WHERE p.person_id = my_person_id) THEN ...

SELECTリストは の結果には影響しませんEXISTS。適格な行が少なくとも 1 つ存在することだけが重要です。

于 2012-08-09T22:18:13.633 に答える
5

使用回数(*)

declare 
   cnt integer;
begin
  SELECT count(*) INTO cnt
  FROM people
  WHERE person_id = my_person_id;

IF cnt > 0 THEN
  -- Do something
END IF;

編集(声明を読んでいない反対票を投じた人や、同様のことをしている可能性のある人向け)

ソリューションは、列にwhere句があるためにのみ有効です(列の名前は、主キーであることを示唆しているため、where句は非常に効果的です)

そのwhere句のため、主キーによって識別される行の存在をテストするために LIMIT などを使用する必要はありません。これをテストするのは効果的な方法です

于 2012-08-09T21:40:12.710 に答える