Sql 如何保证一个表只有一行一列?
使用PostgreSQL 11.5。我需要允许一个表只允许一行和一列(不是0或2,确切地说是1)。我觉得Sql 如何保证一个表只有一行一列?,sql,postgresql,database-design,permissions,check-constraints,Sql,Postgresql,Database Design,Permissions,Check Constraints,使用PostgreSQL 11.5。我需要允许一个表只允许一行和一列(不是0或2,确切地说是1)。我觉得addconstraint会很有用,但我不确定该怎么办 我希望能够在需要时更新此行 使以下内容有效的内容: foo ----- bar 但不包括以下内容: foo | baz -----+----- bar | bin -----+----- | gar 您可以强制表只有一行,在主键(或任何其他唯一且不可为空的coulmn)上设置CHECK约束,如下所示: ALTER T
addconstraint
会很有用,但我不确定该怎么办
我希望能够在需要时更新此行
使以下内容有效的内容:
foo
-----
bar
但不包括以下内容:
foo | baz
-----+-----
bar | bin
-----+-----
| gar
您可以强制表只有一行,在主键(或任何其他唯一且不可为空的coulmn)上设置
CHECK
约束,如下所示:
ALTER TABLE ADD CONSTRAINT[]检查([pk/唯一字段]=[常量值]);
无论如何,因为您想要有一个可更新的字段,所以需要使用一个包含2列的表。如果您确实只需要一行(并且仅选择foo
或为此目的创建视图不是一个选项),您还可以在插入和删除时使用触发器(并通过引发异常来拒绝其中的任何操作)。为了避免出现空表(不确定是否需要),您还需要在删除时使用此触发器,约束将不够强。有关触发器,请参见此处:
要避免任何进一步的ALTER TABLE
命令(例如添加列)和DROP TABLE
,请使用事件触发器。有关更多信息,请查看文档:
要将PL/pgSQL与触发器一起使用,还可以查看一下您可以强制一个表只有一行,并在主键(或任何其他唯一且不可为null的coulmn)上设置
CHECK
约束,如下所示:
ALTER TABLE ADD CONSTRAINT[]检查([pk/唯一字段]=[常量值]);
无论如何,因为您想要有一个可更新的字段,所以需要使用一个包含2列的表。如果您确实只需要一行(并且仅选择foo
或为此目的创建视图不是一个选项),您还可以在插入和删除时使用触发器(并通过引发异常来拒绝其中的任何操作)。为了避免出现空表(不确定是否需要),您还需要在删除时使用此触发器,约束将不够强。有关触发器,请参见此处:
要避免任何进一步的ALTER TABLE
命令(例如添加列)和DROP TABLE
,请使用事件触发器。有关更多信息,请查看文档:
要将PL/pgSQL与触发器一起使用,还可以查看创建超级用户或某个受信任角色:
CREATE VIEW onerow AS SELECT 'bar' AS foo; -- defaults to type text
GRANT SELECT ON onerow TO public;
创造者是所有者。或:
ALTER VIEW onerow OWNER TO postgres; -- or to a trusted role
每个人都可以像从任何其他表中一样从中选择。
任何人都不能在视图中添加或删除行,甚至不能使用DDL命令更改任何内容。
只有DML命令可以更改它,并且只有所有者或超级用户可以这样做:
CREATE OR REPLACE VIEW onerow AS
SELECT 'bar1' AS foo;
记住,最终,一个有动力的超级用户可以做任何事情
在非常繁忙的系统上,CREATE或REPLACE VIEW
使用的独占锁可能是个问题。这是我能想到的这个解决方案唯一可能的问题
另一方面,考虑这个密切相关的答案,最多允许一行:
您可以这样做,并且(作为超级用户):
超级用户仍然可以删除
或截断
。您也可以通过触发器
或规则
来防止这种情况发生
或者,您可以为插入和删除添加常规触发器
,或为规则
添加规则
一个单独的值可以由函数或“全局变量”提供。见:
创建一个超级用户或某个受信任的角色:
CREATE VIEW onerow AS SELECT 'bar' AS foo; -- defaults to type text
GRANT SELECT ON onerow TO public;
创造者是所有者。或:
ALTER VIEW onerow OWNER TO postgres; -- or to a trusted role
每个人都可以像从任何其他表中一样从中选择。
任何人都不能在视图中添加或删除行,甚至不能使用DDL命令更改任何内容。
只有DML命令可以更改它,并且只有所有者或超级用户可以这样做:
CREATE OR REPLACE VIEW onerow AS
SELECT 'bar1' AS foo;
记住,最终,一个有动力的超级用户可以做任何事情
在非常繁忙的系统上,CREATE或REPLACE VIEW
使用的独占锁可能是个问题。这是我能想到的这个解决方案唯一可能的问题
另一方面,考虑这个密切相关的答案,最多允许一行:
您可以这样做,并且(作为超级用户):
超级用户仍然可以删除
或截断
。您也可以通过触发器
或规则
来防止这种情况发生
或者,您可以为插入和删除添加常规触发器
,或为规则
添加规则
一个单独的值可以由函数或“全局变量”提供。见:
以下是一个可能对您有所帮助的示例:
CREATE TABLE singleton (x SMALLINT NOT NULL UNIQUE CHECK (x=1), foo VARCHAR(10) NOT NULL);
INSERT INTO singleton (x, foo) VALUES (1,'one row');
以下是一个可能对您有所帮助的示例:
CREATE TABLE singleton (x SMALLINT NOT NULL UNIQUE CHECK (x=1), foo VARCHAR(10) NOT NULL);
INSERT INTO singleton (x, foo) VALUES (1,'one row');