如何向sql表添加约束,以便表只有一行

时间:2015-04-03 08:25:33

标签: sql postgresql database-design

最初创建参数表,并在Postgres中添加一行。

此表应始终为一行,否则使用此表的SQL查询将产生不正确的结果。不允许DELETEINSERT到此表,仅允许UPDATE

如何在此表中添加单行约束?
也许DELETEINSERT触发器可以引发异常或者是否有更简单的方法?

3 个答案:

答案 0 :(得分:4)

以下将创建一个表,您只能插入一行。 id列的任何更新都会导致错误,任何插入的值都不会超过42.实际的id值实际上并不重要(除非有一些特殊含义,你需要)。

create table singleton
(
   id integer not null primary key default 42,
   parameter_1 text,
   parameter_2 text,
   constraint only_one_row check (id = 42)
);

insert into singleton values (default);

要防止删除,您可以使用规则:

create or replace rule ignore_delete
  AS on delete to singleton
     do instead nothing;

如果你想insert"失败"你也可以使用规则让insert什么都不做。默默。如果没有该规则,insert将生成错误。如果您希望delete也生成错误,则需要创建一个简单引发异常的触发器。


修改

如果要为插入或删除引发错误,则需要触发:

create table singleton
(
   id integer not null primary key,
   parameter_1  text,
   parameter_2  text
);

insert into singleton (id) values (42);

create or replace function raise_error()
  returns trigger
as
$body$
begin
  RAISE EXCEPTION 'No changes allowed';
end;
$body$
language plpgsql;


create trigger singleton_trg 
  before insert or delete on singleton
  for each statement execute procedure raise_error();

请注意,您必须在创建触发器之前插入单行,否则无法插入该行。

这仅对超级用户或表的所有者有效。两者都有权删除或禁用触发器。但这是超级用户的本质 - 他可以做任何事情。

答案 1 :(得分:1)

要使任何表格成为单身,只需添加此列:

just_me bool NOT NULL DEFAULT TRUE UNIQUE CHECK (just_me)

这只允许一行。另外添加触发器@a_horse provided

但是为了这个目的,我会而不是使用函数而不是表。更简单,更便宜。

CREATE OR REPLACE FUNCTION one_row()
  RETURNS TABLE (company_id int, company text) LANGUAGE sql IMMUTABLE AS
$$SELECT 123, 'The Company'$$
ALTER FUNCTION one_row() OWNER TO postgres;

将所有者设置为应该允许更改它的用户。

没有其他人改变它 - 当然除了超级用户。超级用户可以做任何事情。

您可以像使用表格一样使用此功能:

SELECT * FROM one_row();

如果您需要“表格”,请创建一个视图(实际上是内部的特殊表格):

CREATE VIEW one_row AS SELECT * FROM one_row();

答案 2 :(得分:0)

我猜你不会在你的应用程序中使用PostgreSQL root用户,所以你可以简单地限制你的应用程序用户对这个表的UPDATE的权限。

INSERTDELETE会导致Insufficient privilege例外。