4

次の問題があります。INSERT ステートメントのいくつかの値を変更したいです。たとえば、クエリがあります。

INSERT INTO table(a,b) values(x,y);

しかし、テーブルには別の列cもあります。上記のクエリからbの値を (INSERT の前に) チェックし、その値に応じてc=zを設定したいのですが、挿入したばかりのこの特定の行に対してのみです。

いくつかのトリガーが私の問題に役立つと思いますが、その方法がわかりません。疑似コードをいただければ幸いです。

4

2 に答える 2

3

通常のユーザーのテーブルへの直接アクセスを制限することは、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オプションについての注意。内部で使用されるオブジェクトへのアクセスを許可せずに、関数へのアクセスを許可できます。

于 2013-06-11T03:23:48.560 に答える
2

これはステートメント自体で行うことができ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 *

( WITHPostgres 9.1+ が必要) とRETURNING句は、便宜上テストするためのものです。
重要な部分はSELECTwithCASEステートメントです。

このテストは、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 *
于 2013-06-10T22:46:07.560 に答える