在 Postgres 触发函数中异常调用之前执行操作

2023-11-25

这里是 Postgres 8.4。想象此代码片段来自 Postgres 文档:

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
    -- Check that empname and salary are given
    IF NEW.empname IS NULL THEN
        RAISE EXCEPTION 'empname cannot be null';
    END IF;
    IF NEW.salary IS NULL THEN
        RAISE EXCEPTION '% cannot have null salary', NEW.empname;
    END IF;

    -- Who works for us when she must pay for it?
    IF NEW.salary < 0 THEN
        RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
    END IF;

    -- Remember who changed the payroll when
    NEW.last_date := current_timestamp;
    NEW.last_user := current_user;
    RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;

如果我们想做一些事情,比如记录自定义表,这些异常:

-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
    INSERT INTO my_log_table ('User didn't supplied empname')
    RAISE EXCEPTION 'empname cannot be null';
END IF;

它不会起作用,因为我们在 a 之前放置的任何内容RAISE EXCEPTION调用被回滚撤消RAISE EXCEPTION意味着,即我们创建的 my_log_table 行将被删除RAISE EXCEPTION叫做。

完成这样的事情的最佳方法是什么?也许捕获我们的自定义异常?

关闭回滚@TRIGGER不是一个选项,我需要它。


You can 陷阱错误/ 捕获异常。

In the EXCEPTION阻止您可以执行其他任何操作,例如 INSERT 到另一个表中。之后,您可以重新引发异常以传播出去,但这会回滚整个事务,包括对日志表的插入(除非异常被包装并捕获在外部函数中)。

You could:

  • 使用 dblink 调用等技巧来模拟自治事务,当回滚包装事务时,该事务不会撤消。有关的:

    • 如何在 PostgreSQL 中使用(安装)dblink?
    • dblink 无法在 UPDATE 触发器后更新同一数据库上的表
    • Postgres 是否支持嵌套或自治事务?
  • RAISE a NOTICE or WARNING此外,这也不能撤消ROOLBACK.

  • RAISE不同的EXCEPTION用你自己的文字。

或者,您也可以取消该行触发了触发函数并且not引发异常。交易中的其他一切都正常进行。

假设这是一个触发器ON UPDATE并且您有另一个具有相同结构的表来将失败的 INSERT 写入到:

CREATE OR REPLACE FUNCTION emp_stamp()
  RETURNS trigger AS
$func$
BEGIN
    -- Check that empname and salary are given
    IF NEW.empname IS NULL THEN
         RAISE EXCEPTION 'empname cannot be null';
    END IF;

    IF ...

    RETURN NEW;    -- regular end

EXCEPTION WHEN others THEN  -- or be more specific
    INSERT INTO log_tbl VALUES (NEW.*); -- identical table structure
    RETURN NULL;   -- cancel row
END
$func$ LANGUAGE plpgsql;

注意NEW包含异常发生之前行的状态,包括同一函数中先前成功的语句。

Trigger:

CREATE TRIGGER emp_stamp
BEFORE INSERT OR UPDATE ON tbl
FOR EACH ROW EXECUTE PROCEDURE emp_stamp();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Postgres 触发函数中异常调用之前执行操作 的相关文章

  • 查询外键列可以为NULL的地方

    我想获取数据 如果orgid 2或者如果根本没有行uid orgid is an integer 我能想到的最接近的事情就是做IS NULL但我没有得到数据uid没有一个orgid排 任何想法 select u uid u fname u
  • 在 postgreSQL 上选择大写表名不起作用[重复]

    这个问题在这里已经有答案了 我在 windows7 和 python3 4 4 上使用 psycopg2 我想从大写名称的表中获取数据 但我无法弄清楚 谁能帮我 总是这样返回relation table does not exist我想让
  • Swift 中的运行时错误处理

    我完全知道 Swift 没有 try catch 机制来捕获异常 好吧 Swift 2 0 现在支持它们 我还了解到 许多 API 方法都会返回一个 NSError 如果出现问题 该错误对象将被填充为错误对象 所以请不要向我指出这个问题 S
  • 如何使用 keyTextTransform() 进行嵌套 json?

    我的模型有一个 json 字段 我可以使用以下查询访问 jsonfield key1 from django contrib postgres fields jsonb import KeyTextTransform MyModel obj
  • Postgres 简单的“数据透视表”

    如果我有一个这样的数据表 name type count test blue 6 test2 red 3 test red 4 我怎样才能查询它以获得一个表 name num red num blue test 4 6 test2 3 0
  • 通过 JDBC 将“daterange”字段值插入 PostgreSQL 表

    我在 PostgreSQL 9 3 有一个表日期范围 http www postgresql org docs 9 3 static rangetypes html字段类型 我可以像使用 JDBC 的字符串一样选择此字段 但无法将其插入表中
  • PostgreSQL 函数/存储过程 CURRENT_TIMESTAMP 不变

    我想跟踪函数内的执行时间 作为示例 我有以下状态跟踪表 CREATE TABLE status table run id numeric NOT NULL start ts timestamp 6 without time zone NOT
  • 服务具有零个应用程序(非基础设施)端点

    我最近创建了一个WCF服务 dll 和一个服务主机 exe 我知道我的 WCF 服务工作正常 因为我能够成功地将服务添加到 WcfTestClient 但是 当我从服务主机 exe 使用 WCF 时 我似乎遇到了问题 我可以将对 WCF d
  • 在 Rails 中禁用连接池以使用 PgBouncer

    我们有一个 Ruby on Rails 4 2 8 项目 可以访问大型 PostgreSQL 数据库 我们将使用 PgBouncer 添加一个新的连接池服务器 由于 PgBouncer 将处理数据库连接池 我们是否需要关闭 Rails 自动
  • 查找 PostgreSQL 中所有范围集合的所有交集

    我正在寻找一种有效的方法来查找时间戳范围集之间的所有交集 它需要与 PostgreSQL 9 2 配合使用 假设这些范围代表一个人可以见面的时间 每个人都可以有一个或多个空闲时间范围 我想找到all可以召开会议的时间段 即所有人都有空的时间
  • 更改迁移中的自动​​增量值(PostgreSQL 和 SQLite3)

    我有一个托管在 Heroku 上的项目 想要更改表的自动增量起始值 我在本地使用 SQLite3 Heroku 使用 PostgreSQL 这是我在迁移中所拥有的 class CreateMytable lt ActiveRecord Mi
  • 用户登录时的 Postgresql 触发器

    我正在尝试找出一种方法来了解用户何时登录 Postgres 数据库 有没有办法定义用户登录数据库时触发的触发器 或者是否有一个表或系统视图在任何人登录数据库时都会更新 登录钩子 https github com splendiddata l
  • JAX-WS Soap 错误未出现在 WSDL 中

    我正在使用 JAX WS 创建一个 Web 服务 我正在使用 Java 到 WSDL 方法创建它 我无法让我的例外按照我的要求工作 我创建了以下异常类 WebFault public class MyWebServiceException
  • wal_keep_segments 为什么是最小值而不是最大值?

    根据docs http www postgresql org docs current static runtime config replication html wal keep segments integer 指定过去日志的最小数量
  • 如何 md5 所有列(无论类型如何)

    我想创建一个 sql 查询 或 plpgsql 它将 md5 所有给定的行 无论类型如何 但是 在下面 如果 1 为空 则哈希为空 UPDATE thetable SET hash md5 accountid accounttype cre
  • 无法“安装”plpython3u - postgresql

    我正在尝试在 postgresql 中使用 python 语言 像这样的事情 create or replace function test a integer returns integer as if a 2 0 return even
  • 使用 psycopg2 在 python 中执行查询时出现“编程错误:语法错误位于或附近”

    我正在运行 Python v 2 7 和 psycopg2 v 2 5 我有一个 postgresql 数据库函数 它将 SQL 查询作为文本字段返回 我使用以下代码来调用该函数并从文本字段中提取查询 cur2 execute SELECT
  • PESSIMISTIC_WRITE 是否锁定整个表?

    只是为了确保我正确理解事情是如何运作的 If I do em lock employee LockModeType PESSIMISTIC WRITE 它会仅阻止该实体吗 employee 或整个表Employees 如果重要的话 我正在谈
  • 未捕获 Func<> 的异常(异步)

    我有以下代码 为了进行此重现而进行了简化 显然 catch 异常块将包含更多逻辑 我有以下代码 void Main var result ExecuteAction async gt Will contain real async code
  • 比较两个 postgres 转储文件

    如何比较 postgres 转储文件 我有两个转储文件 dump1 和 dump2 我想比较这两个转储文件 任何帮助将不胜感激 谢谢 如果使用 Windows 则可以使用 Beyond Compare 如果使用 linux fedora 则

随机推荐

  • 添加自定义维度以请求遥测 - Azure 函数

    我正在使用 v2 x 创建一个新的 Function 应用程序 并且正在集成 Application Insights 以进行请求日志记录 这是自动完成的 因为 Azure Function 现在已与 App Insights 集成 如文档
  • C++ 读写同一类的多个对象

    airport air 1 2 3 an airport constructor ofstream myfile myfile open rishab ios app ios binary myfile write char air siz
  • jQuery tablesorter + 调整列宽

    有没有jQuery用于调整与表排序器一起使用的表列大小的插件 看起来像柔性网格有你可能想要的一切
  • 我可以在实体框架中访问 IDbCommandInterceptor 中的实体吗

    实现 IDbCommandInterceptor 时 我可以访问为命令 查询创建的 SQL 命令 是否还可以访问在实现的方法中持久 检索的实际实体对象 这是一些幻想代码来演示我想做的事情 public class WidgetInterce
  • Google 表格支持哪些数据类型?

    我无法在网上或在表格文档中找到答案 Google 表格中的单个单元格支持哪些数据类型 例如 这是我到目前为止所看到的 是否有 Google 表格接受的可接受数据类型列表 和你一样 我无法找到明确的数据类型列表 不过 通过个人经验和测试 我验
  • JComponent.isShowing() 和 isDisplayable() 之间的区别

    有什么区别Component isShowing and Component isDisplayable 我想用它们来决定是否应该停止 启动计时器 一个组件 isShowing when 确定该组件是否显示在屏幕上 这意味着 该组件必须是可
  • 将 git 文件保存在另一个文件夹中

    如何设置 git 来跟踪文件夹中的文件 a 但存储 git文件夹中的文件夹 b 另外 为了更进一步 我可以保留 git另一台服务器上的文件夹并运行git来自服务器的命令a去检查git st例如 在服务器上b 基本上 我希望能够在某个文件夹上
  • 检查点射线调谐试验的最佳模型

    所以我刚刚跑了一个tune实验并得到以下输出 Trial name status loc lr weight decay loss accuracy trainable 13720f86 TERMINATED
  • 手动添加迁移?

    我首先在项目中使用实体框架代码 并且所有表都已在不久前创建 修改 现在我需要向表添加唯一约束 我想创建一个迁移 其中将包含以下行Up 方法 并且有模型类没有变化 CreateIndex TableName new Column1 true
  • 在 Spring Boot 中将属性放在 application.yml 或 bootstrap.yml 上有什么区别?

    在 Spring Boot 中将属性放在 application yml 或 bootstrap yml 上有什么区别 在logging config 情况下 应用程序的工作方式有所不同 我刚刚问过Spring Cloud伙计们 我认为我应
  • 在 SignalR 中 Hub.Context 线程安全吗?

    如果不同客户端同时发生多个请求 则 Hub Context ConnectionId 的值会在处理程序执行期间发生变化 假设我有 2 个客户端与客户端 ID A 和 B 连接 并且我的 Hub 上有一个名为 foo 的方法 我从 A 向服务
  • 将 CSV 文件转换为 XLSX 并提供两种格式供用户导出的最佳方法

    我实现了一个 CSV 导出器 其工作原理如下 用户触发 CSV 导出 应用程序创建一个新的后台作业 作业生成 CSV 使用CSV generate 作业使用回形针将文件保存在 Amazon S3 上 使用以下命令分配文件 StringIO
  • 相当于 PowerShell 中的 *Nix 'which' 命令?

    如何询问 PowerShell 某物在哪里 例如 which notepad 它会根据当前路径返回运行 notepad exe 的目录 当我开始在 PowerShell 中自定义我的个人资料时 我创建的第一个别名是 which New Al
  • 如何禁用/隐藏 woocommerce 单品页面?

    我试图隐藏我的 wordpress woocommerce 网站上的单个产品详细信息页面 我怎样才能在不破坏 woocommerce 功能的情况下实现这一目标 您可以删除商店页面上生成的锚点 该锚点永远不会将用户重定向到单个页面 为此 您必
  • Android有类似Table的ListView适配器吗

    我正在使用 ListView 来显示项目列表 这些项目采用包含列和行的表格格式 是否有类似适配器的表格来确保所有列和行对齐 我知道这会带来每列应该有多大 如何处理截断文本以及其他问题的复杂性 我只是好奇当前是否有适配器隐藏在某个地方来完成此
  • 如何阻止 PHP 输出缓冲吃掉错误消息?

    好吧 现在我已经深入了解了一点 我意识到这是一个愚蠢的问题 而且是错误的 事实证明 我维护的遗留代码的作者使用以下命令将错误日志劫持到另一个文件中 php init陈述 劫持发生在输出缓冲打开的同时 使得appear好像输出缓冲正在丢弃我的
  • 在Pycharm(Mac)上安装tensorflow

    I was trying to use tensorflow in Pycharm IDE 看来在Pycharm中 是一键安装包的 坎坷不平 这很容易 现在当我尝试安装tensorflow时出现错误 Tensorflow是通过Mac上的终端
  • 所有像素的高效像素着色器总和

    如何使用 HSLS 像素着色器有效计算图像中所有像素的总和 我对 Pixel Shader 2 0 感兴趣 我可以将其作为 WPF 着色器效果进行调用 有一个更简单的解决方案 不使用着色器 将图像加载为纹理 创建 mipmap 链并读回最后
  • 如何通过 HTTP 访问 ejabberd admin api?

    我读到了有关该文档的内容https docs ejabberd im admin api 我想知道如何通过 HTTP 访问这些 API 我尝试访问 但总是404 在你的 ejabberd yml 中你可以找到这样的配置 port 5280
  • 在 Postgres 触发函数中异常调用之前执行操作

    这里是 Postgres 8 4 想象此代码片段来自 Postgres 文档 CREATE FUNCTION emp stamp RETURNS trigger AS emp stamp BEGIN Check that empname a