我目前正在经历尝试学习功能和触发器的成长痛苦。我正试图从我正在阅读的书中解决问题,但我不明白如何做某些部分。
使用此表
create table movies (
id integer primary key,
title varchar(255) not null,
year integer
);
insert into movies values (1, 'The Croods', 2013);
insert into movies values (2, 'Now You See Me', 2013);
insert into movies values (3, 'Argo', 2012);
insert into movies values (4, 'Jurassic World', 2015);
create table discs (
id integer primary key,
movie_id integer not null references movies(id),
type_id integer references disc_types(id),
price decimal(10,2),
available boolean
);
insert into discs values (1, 1, 1, 1.59, 't');
insert into discs values (2, 1, 1, 1.59, 'f');
insert into discs values (3, 1, 2, 2.99, 'f');
insert into discs values (4, 2, 1, 1.29, 't');
insert into discs values (5, 2, 1, 1.29, 't');
insert into discs values (6, 2, 2, 2.99, 't');
insert into discs values (7, 3, 2, 2.59, 't');
insert into discs values (8, 3, 2, 2.59, 't');
create table customers (
id integer primary key,
name varchar(255),
email varchar(255)
);
insert into customers values (1, 'John', 'john@hotmail.com');
insert into customers values (2, 'Jane', 'jane@gmail.com');
create table rentals (
id integer primary key,
customer_id integer not null references customers(id),
disc_id integer not null references discs(id),
date_rented date,
date_returned date
);
insert into rentals values (1, 1, 7, '2013-10-01', '2013-10-03');
insert into rentals values (2, 2, 5, '2013-10-05', '2013-10-06');
insert into rentals values (3, 2, 2, '2013-11-02', null);
insert into rentals values (4, 2, 3, '2013-11-02', null);
create table ratings (
customer_id integer not null references customers(id),
movie_id integer not null references movies(id),
rating integer,
primary key (customer_id, movie_id)
);
insert into ratings values (1, 1, 1);
insert into ratings values (1, 2, 4);
insert into ratings values (1, 3, 5);
insert into ratings values (2, 1, 4);
我的逻辑是,我将拥有将要插入或更新的评级表的新值,并使用这些值与租赁表中的最新情况进行比较,以查看该客户是否已经租用该电影,如果他们这样做了然后他们可以输入评级。但我不能在这个大声笑中转移那个逻辑。除非有更简单的方法来做到这一点。
答案 0 :(得分:0)
函数内部的循环使问题变得复杂,让我们看看是否可以摆脱它。您的评分表中有对客户和电影的引用,因此我们需要加入。
SELECT COUNT(*) INTO rented FROM rentals WHERE disc_id IN
(SELECT id from discs INNER JOIN
rentals ON disc_id = discs.id where movie_id = new.movie_id)
AND customer_id = new.customer_id
这应该使您的存储过程的逻辑更容易。我现在离开你完成它,因为这毕竟是一个学习练习。
您需要这种联接,因为它比循环更有效,更简单。评级表有一个对movie_id的引用,但租借表只有一个disc_id,因此要知道用户是否租用了某个特定的电影,你需要通过光盘表加入它。
您需要更改返回值。参考:http://www.postgresql.org/docs/9.2/static/plpgsql-trigger.html
触发行级触发器BEFORE可以返回null来发出触发信号 经理跳过这一行的其余操作(即 不会触发后续触发器,INSERT / UPDATE / DELETE会触发 不会出现这一行)。如果返回一个非空值,那么 操作继续进行该行值
另请注意,您不要在触发器功能中执行INSERT。您只需返回插入的非null值即可继续。