4

我遇到了以下问题。我想更改 INSERT 语句的一些值,例如有一个查询:

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

但是 table 还有另一列c。我想从上面的查询中检查(在插入之前)b的值,然后根据一个人的值设置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

You can do this in the INSERT statement itself, no trigger needed.

Given table t:

CREATE TEMP TABLE t (a int, b int, c int)

Default for c is NULL.
Consider this demo:

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 *

The WITH (requires Postgres 9.1+) and the RETURNING clause are just for testing convenience .
The important part is the SELECT with the CASE statement.

This test should work for 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 回答