データベースにはユーザーのテーブルが含まれています。ユーザは、ユーザ名がデータベースに送信されるデータの一部(すなわち、関数を介して)の一部であるときは常にテーブルに追加され、ユーザ名はテーブル内で一意でなければならない。特定の関数呼び出しでは、1つのユーザー名が複数回表示されることもあります。volatile関数を呼び出す安定した関数:同時実行の問題
ユーザー名ごとに、既存のIDを取得するか、またはユーザーのテーブルにIDを挿入してIDを返します。
私が思い付いた解決策は、ユーザーテーブルから最初に選択しようとするSTABLE関数です。失敗した場合は、ユーザーのテーブルに挿入しようとするVOLATILEヘルパ関数を呼び出します。私はSTABLEを好むのは、関数の結果がトランザクションの残りの部分で同じになるためです。ユーザー名が複数回含まれている場合や、他の関数に渡された場合に最適化したいと思います。そのIDを探しています。
私の最初の関数のSTABLEは、(ヘルパー関数で例外を引き起こす)同時挿入が初期関数では見られないことを意味し、無限ループを引き起こしますか?
私は以下の定義を含んでいます。
CREATE SCHEMA orgnztn;
CREATE TABLE orgnztn.tUsers (
id serial NOT NULL,
usrid text NOT NULL,
PRIMARY KEY (id),
UNIQUE (usrid)
);
CREATE OR REPLACE FUNCTION orgnztn.getUserID (
IN p_usrid text
)
RETURNS integer
LANGUAGE plpgsql
STABLE
CALLED ON NULL INPUT
SECURITY INVOKER
AS $$
DECLARE
p_id integer;
BEGIN
IF p_usrid IS NULL THEN
RETURN NULL;
END IF;
p_usrid = upper(p_usrid);
LOOP
SELECT id INTO p_id
FROM orgnztn.tUsers
WHERE usrid = p_usrid
FETCH FIRST 1 ROWS ONLY;
IF found THEN
RETURN p_id;
END IF;
BEGIN
RETURN orgnztn.getUserID_helper(p_usrid);
EXCEPTION WHEN unique_violation THEN
-- loop
END;
END LOOP;
END;
$$;
CREATE OR REPLACE FUNCTION orgnztn.getUserID_helper (
IN p_usrid text
)
RETURNS integer
LANGUAGE plpgsql
VOLATILE
CALLED ON NULL INPUT
SECURITY INVOKER
AS $$
DECLARE
p_id integer;
BEGIN
INSERT INTO orgnztn.tUsers (usrid)
VALUES (p_usrid)
RETURNING id INTO p_id;
RETURN p_id;
END;
$$;