在特定条件下获取行以交换表

2024-01-08

我目前有一个父表:

CREATE TABLE members (
    member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
    first_name varchar(20)
    last_name varchar(20)
    address address (composite type)
    contact_numbers varchar(11)[3]
    date_joined date
    type varchar(5)
);

和两个相关表:

CREATE TABLE basic_member (
    activities varchar[3])
    INHERITS (members)
);

CREATE TABLE full_member ( 
    activities varchar[])
    INHERITS (members)
);

如果类型是full详细信息被输入到full_member表或如果类型是basic进入basic_member桌子。我想要的是,如果我运行更新并将类型更改为basic or full该元组进入相应的表。

我想知道我是否可以用如下规则来做到这一点:

 CREATE RULE tuple_swap_full
 AS ON UPDATE TO full_member
 WHERE new.type = 'basic'
 INSERT INTO basic_member VALUES (old.member_id, old.first_name, old.last_name,
 old.address, old.contact_numbers, old.date_joined, new.type, old.activities);

...然后从 full_member 中删除该记录

只是想知道我的规则是否接近或是否有更好的方法。


  • 你不需要

    member_id SERIAL NOT NULL, UNIQUE, PRIMARY KEY
    

    A PRIMARY KEY暗示UNIQUE NOT NULL自动地:

    member_id SERIAL PRIMARY KEY
    
  • 我不会使用硬编码的最大长度varchar(20)。只需使用text http://www.postgresql.org/docs/current/interactive/datatype-character.html如果确实必须强制执行最大长度,请添加检查约束。更容易改变。

  • 语法为INHERITS被损坏了。关键字位于列周围的括号之外。

    CREATE TABLE full_member ( 
        activities text[]
    ) INHERITS (members);
    
  • 表名不一致(membersmember)。我在测试用例中到处使用单数形式。

  • 最后,我不会使用规则来完成任务。 Atrigger AFTER UPDATE似乎更可取。

考虑以下

测试用例:

Tables:

CREATE SCHEMA x;  -- I put everything in a test schema named "x".

-- DROP TABLE x.members CASCADE;
CREATE TABLE x.member (
     member_id SERIAL PRIMARY KEY
    ,first_name text
    -- more columns ...
    ,type text);

CREATE TABLE x.basic_member (
    activities text[3]
) INHERITS (x.member);

CREATE TABLE x.full_member ( 
    activities text[]
) INHERITS (x.member);

触发功能:

数据修改 CTE http://www.postgresql.org/docs/current/interactive/queries-with.html#QUERIES-WITH-MODIFYING (WITH x AS ( DELETE ..)是实现此目的的最佳工具。需要 PostgreSQL 9.1 或更高版本。
对于旧版本,首先INSERT then DELETE.

CREATE OR REPLACE FUNCTION x.trg_move_member()
  RETURNS trigger AS
$BODY$
BEGIN

CASE NEW.type
WHEN 'basic' THEN
    WITH x AS (
        DELETE FROM x.member
        WHERE member_id = NEW.member_id
        RETURNING *
        )
    INSERT INTO x.basic_member (member_id, first_name, type) -- more columns
    SELECT member_id, first_name, type -- more columns
    FROM   x;

WHEN 'full' THEN
    WITH x AS (
        DELETE FROM x.member 
        WHERE member_id = NEW.member_id
        RETURNING *
        )
    INSERT INTO x.full_member (member_id, first_name, type) -- more columns
    SELECT member_id, first_name, type -- more columns
    FROM   x;
END CASE;

RETURN NULL;

END;
$BODY$
  LANGUAGE plpgsql VOLATILE;

Trigger:

请注意,它是一个AFTER触发器并有一个WHEN健康)状况。WHEN条件需要 PostgreSQL 9.0 或更高版本。对于早期版本,您可以将其保留,触发器本身中的 CASE 语句会处理它。

CREATE TRIGGER up_aft
  AFTER UPDATE
  ON x.member
  FOR EACH ROW
  WHEN (NEW.type IN ('basic ','full')) -- OLD.type cannot be IN ('basic ','full')
  EXECUTE PROCEDURE x.trg_move_member();

Test:

INSERT INTO x.member (first_name, type) VALUES ('peter', NULL);

UPDATE x.member SET type = 'full' WHERE first_name = 'peter';
SELECT * FROM ONLY x.member;
SELECT * FROM x.basic_member;
SELECT * FROM x.full_member;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在特定条件下获取行以交换表 的相关文章

随机推荐

  • 如何仅在第一次调用模拟方法时抛出异常?

    我有一个可以多次调用的模拟对象的方法 想想递归 该方法定义如下 public void doCommit 为了让它失败 我使用这个约定 doThrow new RuntimeException when mMockedObject doCo
  • 如何强制单表继承的引用完整性?

    我读过一些比尔 卡尔文的 https stackoverflow com users 20860 bill karwin回答关于单表继承 https stackoverflow com questions 441001 possible t
  • 为什么从类到子类的动态转换要求类是多态的?

    据我了解 动态转换与静态转换的不同之处在于它对 RTTI 的使用 并且如果变量的动态类型 从基类转换为派生类时 不适合 则动态转换会失败 但是 如果我们无论如何都有 RTTI 为什么类必须是多态的才能完成呢 编辑 由于对 多态 一词的使用存
  • 用于触摸 ID 和密码设置的 iOS 首选项 url 方案

    iOS 设置应用程序有很多带有首选项 url 的列表 用于在设置应用程序中打开特定站点 例如https stackoverflow com a 8246814 4266294 https stackoverflow com a 824681
  • JSPDF 在本地保存的文件在 Acrobat 中出现文档 [110] 错误

    我有以下 JavaScript 代码https jsfiddle net d72sgwrc 5 https jsfiddle net d72sgwrc 5 假设要保存屏幕图像 将其转换为 Canvas 并将其保存为 PDF 将文件下载到本地
  • C# 中的 HttpClient 请求有时会失败

    我的 C Windows 应用程序中有类似的代码 public async Task
  • GroupBy 和 Select 扩展方法帮助

    我正在尝试使用以下代码对几个字段进行 GroupBy var cars tmp Select a gt new a Make a Model a Year cars cars Distinct OrderBy a gt a Make The
  • 从 RabbitMQ 队列检索消息

    我希望将 RabbitMQ 实现到我的 PHP 应用程序中 并使用 php amqp 扩展 我唯一的问题是 如何在 PHP 中轻松查询以返回队列的内容 php amqp 似乎不允许我这样做 如果我错了 请在这里帮助我 James 你能在ra
  • Spark on Yarn 容器故障

    供参考 我通过在 hadoop share hadoop common 中添加 Netty 4 1 17 解决了这个问题 无论我尝试运行什么jar 包括来自https spark apache org docs latest running
  • 什么是 DynamicProxyGenAssembly2 程序集?

    我使用 Moq 进行单元测试 为了测试内部接口 我必须向 DynamicProxyGenAssembly2 程序集声明 InternalsVisibleTo 属性 我们运行模糊测试 这很有用 因为我们可以发现这种方法的一些模糊问题 由于 D
  • 如何同时启动两个进程然后等待两个进程完成?

    我想同时启动两个进程 并确保在继续其他步骤之前完成所有进程 你能帮我吗 我已经尝试过线程 它不能同时启动两个线程并等待完成 final CyclicBarrier gate new CyclicBarrier 3 Thread r2 new
  • 具有多个子项的 WPF UserControl

    我有一个用户控件 我希望能够拥有多个子控件 它已经有 StackPanel 作为它的子项 那么我做错了什么 最终 我希望该控件自动包含一些它自己的子元素 然后在使用时允许在其元素之一中放置更多的子元素 我试过MSDN 的如何覆盖逻辑树 ht
  • 设置新窗口的位置

    你好 我打开一个新窗口 a href Hilfe a 此时新窗口出现在左上角 我如何设置位置 以便它出现在其他地方 通过提供top and left window open Default aspx NewWindow top 100 le
  • 如何使用 FSWatch 在 Mac OSX 上查看文件更改?

    我正在尝试使用fswatch https github com alandipert fswatch将 Linux bash 脚本中的以下几行翻译为能够在 Mac OSX 上运行 inotifywait r m myfolder while
  • 对于 EBFE 的 ARM 等效项要发出哪些字节?

    在 x86 中 如果你想引发无限循环 你可以发出一个ebfe http ebfe org 基本上是跳转到当前指令 ARM 中相当于 EBFE 的是什么 那将是0xeafffffe 自身的无条件分支
  • SPARQL 1.1 蕴含机制和使用 FROM 子句的查询

    我目前正在记录 测试 SPARQL 1 1 蕴涵制度 并且建议反复指出 范围图与活动图在图上等效 但它没有指定活动图指的是什么 它是查询中使用的数据集吗 商店中所有图表的并集 作为确定这一点的测试 我得到了这张图的 URIed
  • 安卓配置改变了

    我有兴趣知道当 Android 设备旋转时 即配置更改时 哪些方法被覆盖 onSaveInstanceState onConfigurationChanged onRestoreInstanceState 类似的东西 对我来说 聆听与更改配
  • okhttp 与 HttpURLConnection 的关系

    很多人跟我说 HttpURLConnection 是从 android 4 4 开始基于 okhttp 的 但是当我深入研究okhttp的代码时 OkHttpURLConnection是从HttpURLConnection扩展的子类 那么
  • Java反思:类字段和方法的顺序是否标准化?

    在 Java 类上使用反射来访问所有字段 方法等 这些元素是否有标准化的顺序 在某些标准中指定 当然 我could凭经验检查 但我需要知道它是否总是 相同 EDIT 我等待问题 我需要订单做什么 长话短说 我有 JAXB 注释的类 并且不想
  • 在特定条件下获取行以交换表

    我目前有一个父表 CREATE TABLE members member id SERIAL NOT NULL UNIQUE PRIMARY KEY first name varchar 20 last name varchar 20 ad