次の問題があります。INSERT ステートメントのいくつかの値を変更したいです。たとえば、クエリがあります。
INSERT INTO table(a,b) values(x,y);
しかし、テーブルには別の列cもあります。上記のクエリからbの値を (INSERT の前に) チェックし、その値に応じてc=zを設定したいのですが、挿入したばかりのこの特定の行に対してのみです。
いくつかのトリガーが私の問題に役立つと思いますが、その方法がわかりません。疑似コードをいただければ幸いです。
次の問題があります。INSERT ステートメントのいくつかの値を変更したいです。たとえば、クエリがあります。
INSERT INTO table(a,b) values(x,y);
しかし、テーブルには別の列cもあります。上記のクエリからbの値を (INSERT の前に) チェックし、その値に応じてc=zを設定したいのですが、挿入したばかりのこの特定の行に対してのみです。
いくつかのトリガーが私の問題に役立つと思いますが、その方法がわかりません。疑似コードをいただければ幸いです。
通常のユーザーのテーブルへの直接アクセスを制限することは、goog の慣行です。これはストアド プロシージャを使用して行うことができ、ストアド プロシージャにのみアクセス権を付与します。例(長いコードで申し訳ありません):
create table foo (
a integer,
b integer,
c integer);
--== Create table. Yes, it is no PK, but for example it is not necesarry
create or replace function p_foo_insert(in aa integer, in ab integer) returns integer as
$$
declare
result integer;
begin
insert into foo (a, b, c) values (aa, ab, aa + ab) returning c into result;
return result;
end; $$ language plpgsql SECURITY DEFINER;
--== It is function for row insertion. Inside this function you can do any data manipulation.
select p_foo_insert(1, 2);
--== Test statement. Result must be a + b = 1 + 2 = 3
だから、忘れてinsert into
、ストアドプロシージャを使用してください:o)
PS:SECURITY DEFINER
オプションについての注意。内部で使用されるオブジェクトへのアクセスを許可せずに、関数へのアクセスを許可できます。
これはステートメント自体で行うことができINSERT
、トリガーは必要ありません。
与えられたテーブルt
:
CREATE TEMP TABLE t (a int, b int, c int)
のデフォルトはc
ですNULL
。
次のデモを検討してください。
WITH i(x,y,z) AS (
VALUES
(1, 2, 111)
,(1, 7, 666)
)
INSERT INTO t(a,b,c)
SELECT x, y, CASE WHEN y = 2 THEN z ELSE NULL END
FROM i
RETURNING *
( WITH
Postgres 9.1+ が必要) とRETURNING
句は、便宜上テストするためのものです。
重要な部分はSELECT
withCASE
ステートメントです。
このテストは、pg 8.4 で機能するはずです。
INSERT INTO t(a,b,c)
SELECT x, y, CASE WHEN y = 2 THEN z ELSE NULL END
FROM (
VALUES
(1, 2, 111)
,(1, 7, 666)
) i (x,y,z)
RETURNING *