PostgreSQL 中的约束和断言

2024-03-27

我正在尝试创建一个简单的数据库,其中有一个客户数据表和一个订单数据表。我正在尝试编写一个约束,使客户在某一天订购的商品数量不能超过特定数量。这是我所拥有的:

CREATE TABLE CUSTOMER
(
    CUSTOMER_NUM CHAR(3) PRIMARY KEY,
    CUSTOMER_NAME CHAR(35) NOT NULL,
    STREET CHAR(15),
    CITY CHAR(15),
    STATE CHAR(3),
    ZIP CHAR(5),
);
CREATE TABLE ORDERS
(
    ORDER_NUM CHAR(5) PRIMARY KEY,
    ORDER_DATE DATE,
    CUSTOMER_NUM CHAR(3),

    CONSTRAINT CUSTOMER_NUM_FKEY FOREIGN KEY (CUSTOMER_NUM)
        REFRENCES CUSTOMER (CUSTOMER_NUM) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE CASCADE 
);

这就是我为强制执行此约束而编写的内容,但它不起作用。我认为这是因为 ORDER_NUM 和 ORDER_DATE 从来没有相同的值。

CREATE ASSERTION ITEM_LIMIT
CEHCK(
        (   SELECT COUNT(*)
            FROM CUSTOMER C1, ORDERS O1
            WHERE C1.CUSTOMER_NUM = O1.CUSTOMER_NUM AND
                O1.ORDER_DATE = O1.ORDER_NUM
     ) <= 1000

我的问题是如何让这个限制发挥作用,比如如何限制每天的订单量。


正如@ruakh 已经澄清的那样,没有CREATE ASSERTION在 PostgreSQL 中。只需检查SQL命令列表 http://www.postgresql.org/docs/current/interactive/sql-commands.html。它不在那里。

您可以使用触发器来更新每个客户的计数并结合CHECK约束,但您必须涵盖所有相关的 DML 语句:INSERT、UPDATE、DELETE。可能看起来像这样:

准备现有客户表:

ALTER TABLE customer ADD COLUMN order_ct integer DEFAULT 0;
UPDATE customer SET order_ct = 0;
ALTER TABLE customer ALTER order_ct SET NOT NULL;
ALTER TABLE customer ADD CONSTRAINT order_ct_max1000 CHECK (order_ct <= 1000);

创建触发函数和触发器:

CREATE OR REPLACE FUNCTION trg_order_upaft()
  RETURNS trigger AS
$BODY$
BEGIN

IF OLD.customer_num <> NEW.customer_num THEN
    UPDATE customer
    SET    order_ct = order_ct - 1
    WHERE  customer_num = OLD.customer_num;

    UPDATE customer
    SET    order_ct = order_ct + 1
    WHERE  customer_num = NEW.customer_num;
END IF;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql;

CREATE TRIGGER upaft
  AFTER UPDATE ON orders FOR EACH ROW
  EXECUTE PROCEDURE trg_order_upaft();


CREATE OR REPLACE FUNCTION trg_order_insaft()
  RETURNS trigger AS
$BODY$
BEGIN

UPDATE customer
SET    order_ct = order_ct + 1
WHERE  customer_num = NEW.customer_num;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql;

CREATE TRIGGER insaft
  AFTER INSERT ON orders FOR EACH ROW
  EXECUTE PROCEDURE trg_order_insaft();


CREATE OR REPLACE FUNCTION trg_order_delaft()
  RETURNS trigger AS
$BODY$
BEGIN

UPDATE customer
SET    order_ct = order_ct - 1;
WHERE  customer_num = OLD.customer_num;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql;

CREATE TRIGGER delaft
  AFTER DELETE ON orders FOR EACH ROW
  EXECUTE PROCEDURE trg_order_delaft();

我在触发器之后创建了所有这些触发器 - 这就是为什么可以RETURN NULL。在这种情况下,AFTER 优于 BEFORE。如果任何其他条件可以取消中间的 DML 语句(像其他触发器一样),它的性能会更好。

如果您没有这样的东西,那么 BEFORE 触发器可能会更好。在这种情况下,请务必相应地设置触发功能 RETURN NEW / OLD。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PostgreSQL 中的约束和断言 的相关文章

  • 导出 Azure SQL 数据库时出现错误 SQL71501

    导出 Azure SQL 数据库时出现奇怪的错误 导出一直工作正常 直到最近发生一些架构更改 但现在出现错误 SQL71501 该数据库是V12 兼容性级别130 尽管master数据库仍兼容级别 120 该问题似乎是由一个新的表值函数引起
  • 将 List 作为参数传递到 postgres 的函数中

    我有这样的 Spring 数据存储库接口 public interface MyEntityRepository extends JpaRepository
  • 在调用存储过程 Sql Server 2008 时使用嵌套存储过程结果

    是否可以在另一个存储过程中使用一个存储过程的结果 I e CREATE PROCEDURE dbo Proc1 ID INT mfgID INT DealerID INT AS BEGIN DECLARE Proc1Result UserD
  • Access SQL 查询:查找表中每个不同条目的最新日期行

    All 我确信这是一个非常简单的 SQL 查询问题 但我确信有一个很好的方法 也有一个非常糟糕的方法来做到这一点 如果由我自己决定 我很可能会得到后者 所以 我在 Access 中有一个表 其中的数据如下所示 ID Value As of
  • 在触发器中记录更新操作

    我有一个 UPDATE 触发器 它生成 INSERTED 和 DELETED 表 如下所示 INSERTED Id Name Surname 1 Stack Overflow 2 Luigi Saggese DELETED Id Name
  • Oracle中如何转义单引号? [复制]

    这个问题在这里已经有答案了 我有一列包含某些存储为文本字符串的表达式 其中包括单个引号 例如 错过的交易 包括引号 发生这种情况时如何使用 where 子句 select from table where reason missed tra
  • 想要从字符格式转换为带小数的数字格式

    想要将字符格式 00001000000 转换为10000 00 请帮我 我已经尝试过 select to number 00012300 9999999999 99 nls numeric characters from dual 这个脚本
  • 使用登录名(用户)创建 PostgreSQL 9 角色只是为了执行函数

    我多年来一直在寻找这个 并且尝试了网络上的所有方法但没有成功 我可以在 MSSQL 中做到这一点 但我没有找到在 PostgreSQL 中做到这一点的方法 我想要实现的只是创建一个具有登录名的角色 该角色无法创建 删除或更改数据库 函数 表
  • 使用外部硬盘写入和存储 mysql 数据库

    我已经设置了 mysql 数据库在我的 Mac 上使用 java 和 eclipse 运行 它运行得很好 但现在我将生成大约 43 亿行数据 这将占用大约 64GB 的数据 我存储了大量的密钥和加密值 我有一个 1TB 外部我想用作存储位置
  • postgreSQL 将分区表(带插入触发器)从一台服务器转储和恢复到另一台服务器

    尝试将分区表从一台服务器转储到 PostgreSQL 9 4 5 中的另一台服务器 对 postgres 相当陌生 并继承了该项目 如果需要更多背景信息 请告诉我 dbname gt SELECT COUNT id FROM parent
  • 如何在一列中存储数组或多个值

    运行 Postgres 7 4 是的 我们正在升级 我需要将 1 到 100 个选定项目存储到数据库的一个字段中 98 的情况下 只会输入 1 个项目 而 2 的情况下 如果是这样的话 会输入多个项目 这些项目只不过是文本描述 截至目前 长
  • SQL分组和总结

    我的表如下所示 income date productid invoiceid customerid 300 2015 01 01 A 1234551 1 300 2016 01 02 A 1234552 1 300 2016 01 03
  • pg_stat_activity 中具有“空闲”状态的持久“COMMIT”查询

    如果我查询 select from pg stat activity where application name example application 我得到了很多行 哪个州是idle查询是COMMIT 它们是持久的并且不会消失 一段时
  • 如何将 T-SQL 中的结果连接到列中?

    我正在处理一个查询 它应该给我这样的结果 Name Surname Language Date James Hetfield en gb fr 2011 01 01 Lars Ulrich gb fr ca 2011 01 01 但我的选择
  • 在tomcat中显示Spring-security的SQL错误

    我使用 spring security 框架创建了一个 Web 应用程序 我设置了一个数据库来存储用户及其角色 但 tomcat 给出以下错误 17 sep 2010 11 56 14 org springframework beans f
  • 关系数据库和图数据库的比较

    有人可以向我解释一下 MySQL 等关系数据库与 Neo4j 等图形数据库相比的优缺点吗 在 SQL 中 您有多个表 它们之间有不同的 id 链接 然后你必须加入来连接表 从新手的角度来看 为什么要将数据库设计为需要联接 而不是像图形数据库
  • 为什么 Orchard 在执行内容项查询时如此慢?

    假设我想查询所有 Orchard 用户 ID 并且还想包括那些已被删除 也称为软删除 的用户 该数据库包含大约 1000 个用户 Option A 大约需要 2 分钟 Orchard ContentManagement IContentMa
  • 从Oracle表中删除重复行

    我正在 Oracle 中测试某些内容并使用一些示例数据填充表 但在此过程中我不小心加载了重复记录 因此现在我无法使用某些列创建主键 如何删除所有重复行并只保留其中一行 Use the rowid伪列 DELETE FROM your tab
  • 当列的数据类型为 int 时,如何用字符串替换 null

    我有一个包含 3 列的表和如下示例数据 所有列都是数据类型int 我有这个查询 select foodid dayid from Schedule 我要更换dayid用字符串 ifdayid null 为此我尝试了这个查询 select f
  • 产品和变体 - 设计数据库的最佳方法

    描述 商店可以有产品 鞋子 T 恤等 每个产品可以有许多变体 每个变体可以有不同的价格和库存 例如T 恤有不同的颜色和尺寸 颜色 蓝色 尺寸 L 价格 10 美元 库存 5 颜色 蓝色 尺寸 XL 价格 10 美元 库存 10 颜色 白色

随机推荐

  • 如何将带有值的命令行参数传递给 Inno Setup 编译器,以便我可以在代码中使用它们?

    我有两种可能的构建选项 由于我不希望我的客户使用某些参数启动安装程序 因此我最好将它们传递给编译器并在我的代码中完成所有工作 假设我有变量UNION它可能有两个值 0 and 1 我必须在代码中分析该变量的值 并根据结果包含或不包含某些文件
  • Hibernate与oracle dblink的实现

    刚接触hibernate 有没有办法在hibernate上实现oracle dblink 例如select from tablename dblink在hql中使用 在 Oracle 中为 tablename dblink 创建 SYNON
  • phantomjs 支持 Bayeux 或 WebSockets 吗?

    只是简单的问题 因为我在文档中没有找到任何参考资料 只是一个简单的答案 PhantomJS 1 x 不支持 但 PhantomJS 2 确实支持 websockets PhantomJS 2 0 0 的 Modernizr 输出
  • 如果行数超过 15,则向表中插入与打开行数相等的行数

    My table id sum type 1 3 1 1 6 1 1 6 2 1 3 1 1 3 1 1 6 1 These 1 3 1 是空行 类型始终为 1 总和可以不同 These 1 6 2 是封闭的行 输入 1 sum 空行的总和
  • option.style.display =“none”在 safari 中不起作用[重复]

    这个问题在这里已经有答案了 这是我正在研究的示例 http jsfiddle net 4suwY 5 http jsfiddle net 4suwY 5 HTML
  • 如何从文本文件中只读取一项内容?

    我可以从文件中读入 并且可以通过更改 for 循环中的数字来更改给出的行数 但我不希望文件中的所有数字像这样并排显示 我需要它们全部随机地一一下降 public class Assignment2 public static void ma
  • Python Sklearn.Model_Selection 给出错误,无法导入梳

    我将 train test split 导入为 from sklearn model selection import train test split 并给出错误无法导入名称 comb 我使用的版本是 scipy 0 18 1 和 skl
  • Botconnector 不适用于自签名的 Nodejs 机器人

    我创建了一个简单的机器人 自签名 ssl 证书 显然这不适用于机器人连接器 几秒钟后 我从机器人收到以下错误 error code BadCertificate message An error occurred while sending
  • 获取用户 keycloak Not Found 异常

    我无法像示例中那样获得用户组 样品来自 看看我们的测试套件 例如 UserTest https github com keycloak keycloak blob 2 5 0 Final testsuite integration arqu
  • Winforms 中是否可以从 ListView 拖放到 TreeView?

    如果不可能的话 我还可以使用 2 个 TreeView 控件 我只是不会在第二个 TreeView 控件中具有层次结构 它就像某种存储库 任何代码示例或教程都会非常有帮助 ListView自然不支持拖放 但您可以使用少量代码启用它 http
  • 如何在cordova应用程序中创建两个离子模式?

    您好 在我的应用程序中 我已经有一个用于登录的离子模式 ionicModal fromTemplateUrl templates login html scope scope then function modal scope modal
  • 如何隔离Spring Boot应用程序Redis和Spring Boot会话全局Redis

    据我所知 spring boot和spring session为我们提供了一站式自动配置 但是当我的应用程序使用会话redis和应用程序缓存redis时 不是同一个redis服务器 我该如何配置呢 非常感谢您的回复 事实上 默认情况下 sp
  • OpenGL资源共享策略

    我正在创建一个类似 CAD 的应用程序 基于 Qt 它将是一个多文档界面 每个文档将包含大约 5 个视口 源自 QGLWidget 因此 我需要在整个应用程序中共享平面着色器 然后在每个文档 即 5 个视口 之间共享 3D 资源 存储为 V
  • 在两台显示器上最大化 WPF 窗口

    就像标题一样 我希望我的 WPF 在 2 个显示器上最大化 现在我的电脑有 2 个显示器 我设置 this Width System Windows Forms Screen AllScreens 0 Bounds Width System
  • PhoneGap Android 中的 pdf 查看器

    我正在寻找使用 Phonegap 2 0 的 Android pdf 查看器 我尝试了 childbrowser 插件 它可以在 iOS 上运行 但不能在 Android 上运行 我试过这个http www giovesoft com 20
  • Symfony 2 - 删除表单和 CSRF 令牌

    我有一个来自数据库的条目列表 我希望在每一行的末尾都有一个 删除按钮 这样用户就不必先转到编辑 显示页面来删除条目 我尝试使用 csrf 令牌创建一个隐藏的输入字段 如下所示 return this gt createFormBuilder
  • 如何仅获取 Rails 路由中的查询字符串?

    我正在使用这样的路线 match v1 method gt v1 index 我的目的是捕获 api 方法的名称 然后将请求发送到控制器内的该方法 def index self send params method params end 我
  • Java递归问题

    我在Java中遇到了一个递归面试问题 需要你的帮助 Write a Java function 这样 给定一个 int 数组 是否可以将 int 分为两组 使两组之和相同 并具有以下约束 所有 5 的倍数的值必须在一组中 并且所有是 3 的
  • C 向量/数组列表/链接列表

    我正在用 C 语言编写一个小程序 我需要一种向量 ArrayList LinkedList 但我正在使用 C 语言 知道如何在 C 语言中做这种事情吗 我想存储结构 然后添加 删除一些结构 对于可调整大小的数组 您可以使用malloc an
  • PostgreSQL 中的约束和断言

    我正在尝试创建一个简单的数据库 其中有一个客户数据表和一个订单数据表 我正在尝试编写一个约束 使客户在某一天订购的商品数量不能超过特定数量 这是我所拥有的 CREATE TABLE CUSTOMER CUSTOMER NUM CHAR 3