INSERT INTO另一个表时更新一个表

时间:2018-01-30 08:41:10

标签: sql postgresql

我有一个包含两个表的数据库:

  • 设备
  • 温度

架构如下:

CREATE TABLE IF NOT EXISTS devices(
  device_id serial PRIMARY KEY,
  device_name varchar(255) UNIQUE NOT NULL,
  last_record_time timestamp without time zone DEFAULT '1995-10-30 10:30:00'
);

CREATE TABLE IF NOT EXISTS temperature(
  device_id integer NOT NULL,
  temperature decimal NOT NULL,
  record_time timestamp without time zone NOT NULL,
  CONSTRAINT temperature_device_id_fkey FOREIGN KEY (device_id)
    REFERENCES devices (device_id) MATCH SIMPLE
    ON UPDATE NO ACTION ON DELETE NO ACTION
);

devices表保存所有设备的列表。因此每个设备都有一个唯一的ID。温度表汇总来自所有设备的数据。您可以通过device_id选择查看与特定设备相关的所有条目。

我有一个约束,我无法从设备表中删除,因为温度表取决于它。我还希望在将新记录插入温度表时更新设备表。

也就是说,温度中新记录的record_time应该成为设备表中该设备条目的last_record_time。这样我总是知道设备最后一次插入数据的时间。

我目前正在以编程方式执行此操作。我插入记录,立即选择它们然后写入另一个表。这引入了一些错误。所以,我宁愿在数据库级别自动执行此操作。我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

使用触发器的替代方法是CTE:

WITH ins AS (
  INSERT INTO temperature (device_id, temperature, record_time)
  VALUES (1, 35.21, '2018-01-30 09:55:23')
  RETURNING device_id, record_time
)
UPDATE devices AS d SET last_record_time = ins.record_time
FROM ins
WHERE d.device_id = ins.device_id;

答案 1 :(得分:0)

使用触发器隐式执行此操作。

在温度表上为触发器内的事件(如插入/删除/更新和更新温度表)创建触发器。

CREATE OR REPLACE FUNCTION update_last_record_time()
    RETURNS trigger AS
$$
BEGIN
    UPDATE devices
    SET last_record_time = NEW.record_time
    WHERE device_id = NEW.device_id;

    RETURN NEW;
END;

$$ LANGUAGE 'plpgsql';

CREATE TRIGGER my_trigger
AFTER INSERT
ON temperature
FOR EACH ROW
EXECUTE PROCEDURE update_last_record_time();

答案 2 :(得分:0)

用于从子表中删除行在创建外键时使用级联删除当父表记录将被删除时,它将自动删除子表中的记录