AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 286498
Accepted
Robert Elliot
Robert Elliot
Asked: 2021-03-06 05:24:43 +0800 CST2021-03-06 05:24:43 +0800 CST 2021-03-06 05:24:43 +0800 CST

如何在同一个表的列之间定义一对多约束?

  • 772

我正在 PostgreSQL 中创建一个 IDs 表来表示多个外部 ID 之间的关系 - 称它们为a,b和c.

我碰巧知道外国ID之间有一对多的关系:

a 1..* b b 1..* c

a我想将它们表示为一个表(见下文),但在& b、 & 和 之间b强制执行一对多不变量c。

那可能吗?

示例:以下插入是非法的:

PK 一个 b C 原因
p15 a1 b11 c111 c111 已经存在
p16 a1 b21 c213 a2 的 b21 已存在
p17 a2 b11 c214 a1 的 b11 已存在

给定以下合法表格:

PK 一个 b C
p1 a1 b11 c111
p2 a1 b11 c112
p3 a1 b12 c121
p4 a1 b12 c122
p5 a2 b21 c211
p6 a2 b21 c212
p7 a2 b22 c221
p8 a2 b22 c222
p9 无效的 b31 c311
p10 a3 无效的 c312
p11 a3 b31 无效的
p12 无效的 无效的 c314
p13 无效的 b31 无效的
p14 a3 无效的 无效的
postgresql constraint
  • 1 1 个回答
  • 148 Views

1 个回答

  • Voted
  1. Best Answer
    nbk
    2021-03-06T07:32:30+08:002021-03-06T07:32:30+08:00

    这必须由 完成,因为它对于约束TRIGGER来说太复杂了CHEKC

    对于更新,您需要类似的触发器/功能

    CREATE TABLE tabl1
        ("pk" varchar(5), "a" varchar(6), "b" varchar(6), "c" varchar(6))
    ;
        
    INSERT INTO tabl1
        ("pk", "a", "b", "c")
    VALUES
        ('p1', 'a1', 'b11', 'c111'),
        ('p2', 'a1', 'b11', 'c112'),
        ('p3', 'a1', 'b12', 'c121'),
        ('p4', 'a1', 'b12', 'c122'),
        ('p5', 'a2', 'b21', 'c211'),
        ('p6', 'a2', 'b21', 'c212'),
        ('p7', 'a2', 'b22', 'c221'),
        ('p8', 'a2', 'b22', 'c222'),
        ('p9', NULL, 'b31', 'c311'),
        ('p10', 'a3', NULL, 'c312'),
        ('p11', 'a3', 'b31', NULL),
        ('p12', NULL, NULL, 'c314'),
        ('p13', NULL, 'b31', NULL),
        ('p14', 'a3', NULL, NULL)
    ;
    
    CREATE OR REPLACE FUNCTION check_insert()
    RETURNS TRIGGER AS $$
       BEGIN
       IF EXISTS(SELECT 1 FROM tabl1 WHERE "c" = NEW."c" AND "b" = NEW."b" ) then
           raise EXCEPTION 'The column %  already  with %',NEW."c",NEW."b";
       ELSIF EXISTS(SELECT 1 FROM tabl1 WHERE "a" <> NEW."a" AND "b" = NEW."b" ) then
               raise EXCEPTION 'The column %  already  has already a column',NEW."b";
       END IF;
       RETURN NEW;
       END;
    $$ LANGUAGE plpgsql;
    
    CREATE  TRIGGER trigger_name BEFORE
     INSERT
    ON tabl1
    FOR EACH ROW
    EXECUTE PROCEDURE check_insert();
    
    INSERT INTO tabl1
        ("pk", "a", "b", "c")
    VALUES
        ('p15', 'a1', 'b11', 'c111')
    
    错误:列 c111 已包含 b11
    

    上下文: PL/pgSQL 函数 check_insert() 第 4 行,位于 RAISE

    INSERT INTO tabl1
        ("pk", "a", "b", "c")
    VALUES
    ('p16' , 'a1'   , 'b21'  , 'c213' )
    
    错误:b21 列已经有一个列
    

    上下文: PL/pgSQL 函数 check_insert() 第 6 行,位于 RAISE

    INSERT INTO tabl1
        ("pk", "a", "b", "c")
    VALUES
    ('p17',   'a2',   'b11'   ,'c214')
    
    错误:b11 列已经有一个列
    

    上下文: PL/pgSQL 函数 check_insert() 第 6 行,位于 RAISE

    SELECT * FROM tabl1
    
    PK | 一个 | 乙 | C   
    :-- | :--- | :--- | :---
    p1 | a1 | b11 | c111
    p2 | a1 | b11 | c112
    p3 | a1 | b12 | c121
    p4 | a1 | b12 | c122
    p5 | a2 | b21 | c211
    p6 | a2 | b21 | c212
    p7 | a2 | b22 | c221
    p8 | a2 | b22 | c222
    p9 | 空| b31 | c311
    p10 | a3 | 空| c312
    p11 | a3 | b31 | 空
    p12 | 空| 空| c314
    第 13 页 | 空| b31 | 空
    p14 | a3 | 空| 无效的
    

    db<>在这里摆弄

    • 2

相关问题

  • 我可以在使用数据库后激活 PITR 吗?

  • 运行时间偏移延迟复制的最佳实践

  • 存储过程可以防止 SQL 注入吗?

  • PostgreSQL 中 UniProt 的生物序列

  • PostgreSQL 9.0 Replication 和 Slony-I 有什么区别?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve